のんびりしているエンジニアの日記

ソフトウェアなどのエンジニア的な何かを書きます。

DesignPattern AbstractFactory(部品を一纏めにしたい貴方へ)

Sponsored Links

皆さんこんにちは。
お元気ですか?私は元気です。

さて、本日はDesignPatternのAbstractFactoryについて

AbstractFactoryとは?

日本語訳をすると抽象的な工場ですね。
似たようなインスタンスの生成を一箇所に纏めることによってとっかえひっかえできるようにする(再利用の効率化)を図る為のデザインパターンです。

メリット

①具体的なクラスをクライアントから隠蔽する
内部の構造を意識せず、プログラマがプログラムを組むことができる。

②利用する部品群の整合性を保つ
各部品ごとに一括りになっているので、各部品単位での整合性を保つのが簡単

③部品群の単位で切り替えができる
Factory自体を別に切り替えればおk

弱点

工場で新しいメソッドを定義したりすると変更が複数箇所で発生する
まぁ仕方ないです。

クラス図

f:id:tereka:20140613000438p:plain

ソースコード

#include <iostream>

#define PEN

using namespace std;

//商品
class Product{
public:
	virtual void createContent() = 0;
};

class PenProduct:public Product{
	void createContent(){
		cout << "create PenProduct" << endl;
	}
};

class PaperProduct:public Product{
	void createContent(){
		cout << "create PaperProduct" << endl;
	}
};

//素材
class Material{
public:
	virtual void createMaterial() = 0;
};

class Ink:public Material{
	void createMaterial(){
		cout << "create Ink" << endl;
	}
};

class Hinoki:public Material{
	void createMaterial(){
		cout << "create Hinoki" << endl;
	}
};

//抽象工場クラス
class abstractFactory{
public:
	virtual Product* createProduct() = 0;
	virtual Material* createMaterial() = 0;
};

class PenFactory:public abstractFactory{
	Product* createProduct(){
		return new PenProduct();
	}

	Material* createMaterial(){
		return new Ink();
	}
};

class PaperFactory:public abstractFactory{
	Product* createProduct(){
		return new PaperProduct();
	}

	Material* createMaterial(){
		return new Hinoki();
	}
};

int main(int argc, char const *argv[]){
	/* code */
#ifdef PEN
	abstractFactory *factory = new PenFactory();
#else
	abstractFactory *factory = new PaperFactory();
#endif
	Product* product = factory->createProduct();
	Material* material = factory->createMaterial();
	product->createContent();
	material->createMaterial();
	return 0;
}

解説

abstractFactoryを継承させたPenFactory,PaperFactoryからそれぞれ必要な商品(createProduct)、素材(createMaterial)を呼び出し、返しています。

main内部ではabstractFactoryクラスに利用するFactoryのポインタを作り、更に、その中から必要な商品と素材を生成する動作を行っています。

今回のメリットは何かというと
このcreateContentやcreateMaterialのメンバ関数内で何が製造されているのかは知りませんが、それに対し、メソッドを実行できる。いわば隠蔽がされているというのが最大のメリットです

こうすることによってコードの書き換えが最低限に済み、取替が容易となります。