Builderパターン

生成プロセスが異なるオブジェクトを、同処理で生成できるようにするパターンです。

実際にオブジェクトを作成するBuilderクラス
Builderクラスの使用方法を唯一知っているDirectorクラス

の二つを使って実装します。

ユーザー側はDirectorクラスに対して「Builderクラスを使ってオブジェクト作ってよ」と
命令を与えるスタイルになります。

現場監督(Directorクラス)が大工さん(Builder)をこき使ってオブジェクト(家)を作成する流れ。
(いつもどおり実行確認してないので注意)


// 大工さん基底(BuilderBase)
class CarpenterBase
{
public:
virtual void MakeSkelton() = 0;
virtual void MakeSystemBath() = 0;
virtual void MakeBedRoom() = 0;
virtual void MakeRoof() = 0;
virtual void MakeWall() = 0;
};

// 腕利きの大工さん(Builder)
class CarpenterGood : public CarpenterBase
{
public:
CarpenterGood(){}
~CarpenterGood(){}

public:
void MakeSkelton(){printf("骨組みつくるよ!");}
void MakeSystemBath(){printf("システムバスつくるよ!");}
void MakeBedRoom(){printf("ベッドルームつくるよ!")}
void MakeRoof(){printf("屋根つくるよ!");}
void MakeWall(){printf("壁つくるよ!");}
};

// インチキな大工さん(Builder)
class CarpenterBad : public CarpenterBase
{
public:
CarpenterBad(){}
~CarpenterBad(){}

public:
void MakeSkelton(){printf("骨組みつくるよ!");}
void MakeSystemBath(){printf("さぼるよ!");} // こらこら
void MakeBedRoom(){printf("ベッドルームつくるよ!")} // これはまとも
void MakeRoof(){printf("穴あき屋根つくるよ!");} // だめだろ
void MakeWall(){printf("でこぼこの壁つくるよ!");} // あああ
};

// 現場監督(Director)
class Foreman
{
public:
Foreman(CarpenterBase* p)
{
SetCarpenter(p);
}
~Foreman(){}

void Order()
{
if (m_pCarpenter)
{
m_pCarpenter->MakeSkelton(); // まずは骨組みからだろ
m_pCarpenter->MakeSystemBath(); // システムバスを作る
m_pCarpenter->MakeBedRoom(); // ベッドルームも作る
m_pCarpenter->MakeRoof(); // 屋根作るよー
m_pCarpenter->MakeWall(); // 壁作るよー
}
}
void SetCarpenter(CarpenterBase* p){m_pCarpenter = p;}
private:
CarpenterBase* m_pCarpenter; // 現場監督が面倒を見る大工さん
};

void Main()
{
// 良い大工さんを生成
CarpenterBase* pCarpenterGood = new CarpenterGood();
// ダメな大工さんを生成
CarpenterBase* pCarpenterBad = new CarpenterBad();
// 現場監督を作成
Foreman* pForeman = new Foreman(pCarpenterGood); // 現場監督する対象の大工さんを与える
// 現場監督が大工さんに指示を出しました
pForeman->Order();

// 現場監督がダメな大工さんを雇ってしまった・・・
pForeman->SetCarpenter(pCarpenterBad);
// あああやめてぇぇぇ欠陥住宅が出来上がるー
pForeman->Order();

}


現実だったら現場監督も大工も解雇されるね。
(ていうか現場監督の役割あってるか?)