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

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

DesignPattern Builder(組み立てを固定化したい貴方へ)

Sponsored Links

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

さて、今回はDesignPatternのBuilderを解説します

Builderとは?

構築者という意味ですね。
今回の例でありますが、色んなパターンのピザを作りたいと思った時に色々なメソッドを呼びたいと
そんな時にビルダーに構築パターンのメソッドを用意して、それらに作ってもらうようなパターン。

ピザショップ:実行する人
Builder:実際に作る人
Pizza:実際の商品

利点

①色々なパターンのビルダーを用意することで様々なパターンの製造に対応ができます。
②複雑なメソッドの組み合わせでも、一括して実行ができます。つまり、毎度毎度書くことによる書き損じ(ミス)を削ることが出来ます。

クラス図

f:id:tereka:20140615224629p:plain

#include <string>
#include <iostream>

using namespace std;

//ピザ
class Pizza{
private:
	int pizza_cheese;
	int pizza_source;
	int pizza_meat;
public:
	void setCheese(const int &cheese){
		pizza_cheese = cheese;
	}

	void setSource(const int &source){
		pizza_source = source;
	}

	void setMeat(const int &meat){
		pizza_meat = meat;
	}
	void open(){
		cout << "cheese " << pizza_cheese << endl;
		cout << "source " << pizza_source << endl;
		cout << "meat " << pizza_meat << endl;
	}
};

//ピザを組み立てるビルダー
class PizzaBuilder{
public:
	Pizza* getPizza(){
		return pizza;
	}

	void createNewPizza(){
		pizza = new Pizza();
	}

	virtual void makeCheese() = 0;
	virtual void makeSource() = 0;
	virtual void makeMeat() = 0;
protected:
	Pizza *pizza;
};

class DominoPizzaBuilder:public PizzaBuilder{
public:
	virtual void makeCheese(){
		pizza->setCheese(30);
	};
	virtual void makeSource(){
		pizza->setSource(40);
	};
	virtual void makeMeat(){
		pizza->setMeat(50);
	};
};

class PizzaHatBuilder:public PizzaBuilder{
public:
	virtual void makeCheese(){
		pizza->setCheese(60);
	};
	virtual void makeSource(){
		pizza->setSource(70);
	};
	virtual void makeMeat(){
		pizza->setMeat(100);
	};
};

//ピザショップでピザを作る
class PizzaShop{
public:
	void setPizzaBuilder(PizzaBuilder* pizzabuilder){
		pizzaBuilder = pizzabuilder;
	}
	Pizza *getPizza(){
		return pizzaBuilder->getPizza();
	}
	void makePizza(){
		pizzaBuilder->createNewPizza();
		pizzaBuilder->makeCheese();
		pizzaBuilder->makeMeat();
		pizzaBuilder->makeSource();
	}
private:
	PizzaBuilder *pizzaBuilder;
};

int main(int argc, char const *argv[]){
	PizzaShop *pizzashop = new PizzaShop;
	Pizza *pizza;

	//ど◯のピザを制作
	PizzaBuilder *pb = new DominoPizzaBuilder;
	pizzashop->setPizzaBuilder(pb);
	pizzashop->makePizza();
	pizza = pizzashop->getPizza();
	pizza->open();

	//ぴざは◯とのピザを制作
	pb = new PizzaHatBuilder;
	pizzashop->setPizzaBuilder(pb);
	pizzashop->makePizza();
	pizza = pizzashop->getPizza();
	pizza->open();

	return 0;
}

PizzaShopがSetしたBuilderに製造内容を任せてしまいます。
こうすることによりBuilderの内容を意識せず、ピザを作ることができます。
後はBuilderにそれぞれの必要な処理を書くことでPizzaShopの内容を変更せず、Builderを増やすだけで拡張性をも担保することができます。