Skeleton of GOF's Design Pattern


ABSTRACTFACTORYの骸骨

ABSTRACTFACTORY

実装に依存する部分を意識せずに、複数の部品群を生成するためのパターンです。

このパターンを用いて部品群の生成を行えば、クライアントは抽象化クラスだけを扱うことができ、クライアントとフレームワーク間の依存関係を疎にすることができます。その結果フレームワークの保守性とポータビリティ性を向上させることができます。 java.awt.Toolkit がまさに、このパターンにあたります。


■ 『ABSTRACTFACTORYの骸骨』の構造


■ 『ABSTRACTFACTORYの骸骨』 プログラム・コード

□ Java2版
// Copyright(C) 2000-2003 Yoshinori Oota All rights reserved.

public class AbstractFactorySample {

    static AbstractFactory Create(String sw) {
        if (sw.equals("A")) {
            return new AbstractFactoryA();
        } else if (sw.equals("B")) {
            return new AbstractFactoryB();
        }
        return null;
    }

    static public void main(String[] args) { 
        AbstractFactory factory = Create("A");
        ProductA a = factory.CreateProductA();
        ProductB b = factory.CreateProductB();
        a.Operation();
        b.Operation();

        factory = Create("B");
        a = factory.CreateProductA();
        b = factory.CreateProductB();
        a.Operation();
        b.Operation();
    }
}

abstract class AbstractFactory { 
    abstract public ProductA CreateProductA();
    abstract public ProductB CreateProductB();
}
				
class AbstractFactoryA extends AbstractFactory { 
    public ProductA CreateProductA() { 
        return new ProductA1(); 
    }
    public ProductB CreateProductB() {
        return new ProductB1();
    }
}

class AbstractFactoryB extends AbstractFactory { 
    public ProductA CreateProductA() { 
        return new ProductA2(); 
    } 
    public ProductB CreateProductB() {
        return new ProductB2();
    }
}

abstract class ProductA { 
    abstract void Operation(); 
}

abstract class ProductB {
    abstract void Operation();
}

class ProductA1 extends ProductA { 
    public void Operation() { 
        System.out.println("ProductA1"); 
    } 
}

class ProductB1 extends ProductB { 
    public void Operation() { 
        System.out.println("ProductB1"); 
    } 
}
class ProductA2 extends ProductA {
    public void Operation() {
        System.out.println("ProductA2");
    }
}
class ProductB2 extends ProductB {
    public void Operation() {
        System.out.println("ProductB2");
    }
}

○ C++版
// Copyright(C) 2003 Yoshinori Oota All rights reserved.
#include <iostream>
using namespace std;

class ProductA {
public:
    ProductA();
    virtual ~ProductA();
    virtual void Operation() const = 0;
};

class ProductB {
public:
    ProductB();
    virtual ~ProductB();
    virtual void Operation() const = 0;
};

class ProductA1 : public ProductA {
public:
    ProductA1();
    virtual ~ProductA1();
    virtual void Operation() const;
};

class ProductB1 : public ProductB {
public:
    ProductB1();
    virtual ~ProductB1();
    virtual void Operation() const;
};

class ProductA2 : public ProductA {
public:
    ProductA2();
    virtual ~ProductA2();
    virtual void Operation() const;
};

class ProductB2 : public ProductB {
public:
    ProductB2();
    virtual ~ProductB2();
    virtual void Operation() const;
};

class AbstractFactory {
public:
    AbstractFactory();
    virtual ~AbstractFactory();
    virtual ProductA* CreateProductA() = 0;
    virtual ProductB* CreateProductB() = 0;
};

class AbstractFactoryA : public AbstractFactory {
public:
    AbstractFactoryA();
    virtual ~AbstractFactoryA();
    virtual ProductA* CreateProductA();
    virtual ProductB* CreateProductB();
};

class AbstractFactoryB : public AbstractFactory {
public:
    AbstractFactoryB();
    virtual ~AbstractFactoryB();
    virtual ProductA* CreateProductA();
    virtual ProductB* CreateProductB();
};


ProductA::ProductA() { }
ProductA::~ProductA() { }

ProductB::ProductB() { }
ProductB::~ProductB() { }

ProductA1::ProductA1() { }
ProductA1::~ProductA1() { }
void ProductA1::Operation() const {
    cout << "ProductA1" << endl;
}

ProductB1::ProductB1() { }
ProductB1::~ProductB1() { }
void ProductB1::Operation() const {
    cout << "ProductB1" << endl;
}

ProductA2::ProductA2() { }
ProductA2::~ProductA2() { }
void ProductA2::Operation() const {
    cout << "ProductA2" << endl;
}

ProductB2::ProductB2() { }
ProductB2::~ProductB2() { }
void ProductB2::Operation() const {
    cout << "ProductB2" << endl;
}


AbstractFactory::AbstractFactory() { }
AbstractFactory::~AbstractFactory() { }

AbstractFactoryA::AbstractFactoryA() { }
AbstractFactoryA::~AbstractFactoryA() { }
ProductA* AbstractFactoryA::CreateProductA() {
    return new ProductA1();
}
ProductB* AbstractFactoryA::CreateProductB() {
    return new ProductB1();
}

AbstractFactoryB::AbstractFactoryB() { }
AbstractFactoryB::~AbstractFactoryB() { }
ProductA* AbstractFactoryB::CreateProductA() {
    return new ProductA2();
}
ProductB* AbstractFactoryB::CreateProductB() {
    return new ProductB2();
}

AbstractFactory* Create(char sw) {
    if (sw == 'A') {
        return new AbstractFactoryA();
    } else if (sw == 'B') {
        return new AbstractFactoryB();
    }
}


int main() {
    AbstractFactory* factory = Create('A');
    ProductA* a = factory->CreateProductA();
    ProductB* b = factory->CreateProductB();
    a->Operation();
    b->Operation();
    delete a;
    delete b;
    delete factory;

    factory = Create('B');
    a = factory->CreateProductA();
    b = factory->CreateProductB();
    a->Operation();
    b->Operation();
    delete a;
    delete b;
    delete factory;

    return 0;
}

○ C版
/* Copyright (C) 2009 Yoshinori Oota All rights reserved. */
#include <stdio.h>
#include <stdlib.h>

enum PRODUCT_TYPE { PRODUCT_A, PRODUCT_B };
enum FACTORY_TYPE { FACTORY_A, FACTORY_B };

/* Product Interface */
struct Product {
    void (*Operation)();
};
struct Product* New_Product(enum PRODUCT_TYPE p_type, enum FACTORY_TYPE f_type);
void Delete_Product(struct Product* product);
void ProductA1_Operation();
void ProductA2_Operation();
void ProductB1_Operation();
void ProductB2_Operation();

/* AbstractFactory Interface */
struct AbstractFactory {
    struct Product* (*CreateProductA)();
    struct Product* (*CreateProductB)();
};
struct AbstractFactory* New_AbstractFactory(enum FACTORY_TYPE type);
void Delete_AbstractFactory(struct AbstractFactory* factory);
struct Product* AbstractFactory_CreateProductA1();
struct Product* AbstractFactory_CreateProductB1();
struct Product* AbstractFactory_CreateProductA2();
struct Product* AbstractFactory_CreateProductB2();

/* Product Class Implementation */
struct Product* New_Product(enum PRODUCT_TYPE p_type, enum FACTORY_TYPE f_type) {
    struct Product* product = NULL;
    product = (struct Product*)malloc(sizeof(struct Product));
    switch (p_type) {
    case PRODUCT_A:
        switch (f_type) {
        case FACTORY_A:
            product->Operation = &ProductA1_Operation;
            break;
        case FACTORY_B:
            product->Operation = &ProductA2_Operation;
            break;
        }
        break;
    case PRODUCT_B:
        switch (f_type) {
        case FACTORY_A:
            product->Operation = &ProductB1_Operation;
            break;
        case FACTORY_B:
            product->Operation = &ProductB2_Operation;
            break;
        }
        break;
    }
    return product;
}

void Delete_Product(struct Product* product) {
    if (product == NULL) {
        return;
    }
    free(product);
    product = NULL;
    return;
}

void ProductA1_Operation() {
    printf("ProductA1\n");
    return;
}

void ProductA2_Operation() {
    printf("ProductA2\n");
    return;
}

void ProductB1_Operation() {
    printf("ProductB1\n");
    return;
}

void ProductB2_Operation () {
    printf("ProductB2\n");
    return;
}

/* AbstractFactory Class Implementation */
struct AbstractFactory* New_AbstractFactory(enum FACTORY_TYPE type) {
    struct AbstractFactory* factory = NULL;
    factory = (struct AbstractFactory*)malloc(sizeof(struct AbstractFactory));
    switch (type) {
    case FACTORY_A:
        factory->CreateProductA = &AbstractFactory_CreateProductA1;
        factory->CreateProductB = &AbstractFactory_CreateProductB1;
        break;
    case FACTORY_B:
        factory->CreateProductA = &AbstractFactory_CreateProductA2;
        factory->CreateProductB = &AbstractFactory_CreateProductB2;
        break;
    }
    return factory;
}

void Delete_AbstractFactory(struct AbstractFactory* factory) {
    if (factory == NULL) {
        return;
    }
    free(factory);
    factory = NULL;
    return;
}

struct Product* AbstractFactory_CreateProductA1() {
    return New_Product(PRODUCT_A, FACTORY_A);
}

struct Product* AbstractFactory_CreateProductB1() {
    return New_Product(PRODUCT_B, FACTORY_A);
}

struct Product* AbstractFactory_CreateProductA2() {
    return New_Product(PRODUCT_A, FACTORY_B);
}

struct Product* AbstractFactory_CreateProductB2() {
    return New_Product(PRODUCT_B, FACTORY_B);
}

struct AbstractFactory* Create(char sw) {
    if (sw == 'A') {
        return New_AbstractFactory(FACTORY_A);
    } else if (sw == 'B') {
        return New_AbstractFactory(FACTORY_B);
    }
    return NULL;
}

int main() {
    struct AbstractFactory* factory = NULL;
    struct Product* a = NULL;
    struct Product* b = NULL;

    factory = Create('A');
    a = factory->CreateProductA();
    b = factory->CreateProductB();
    a->Operation();
    b->Operation();
    Delete_Product(a);
    Delete_Product(b);
    Delete_AbstractFactory(factory);

    factory = Create('B');
    a = factory->CreateProductA();
    b = factory->CreateProductB();
    a->Operation();
    b->Operation();
    Delete_Product(a);
    Delete_Product(b);
    Delete_AbstractFactory(factory);

    return 0;
}


改訂履歴

2009.2.15 C言語版を追加
     
     

ご意見、ご感想はこちらまで。

Copyright(C) 2000-2009 Yoshinori Oota All rights reserved.

本ホームページのリンクは自由です。複製、転載される場合は、必ず著者までご連絡をください。