前序
小菜和大鳥兩人出去吃夜宵,大鳥要了份炒飯,小菜要了份炒面。炒完後大鳥看到炒面感覺不錯,於是也叫了一份。大鳥嘗後感覺淡而無味,於是便問小菜:“為什麼你的炒面好吃,而我再要的炒面卻沒有放鹽?這好吃不好吃是由誰決定的?”小菜答道:“當然是燒菜的人,他感覺好,就是一盤好面,要是心情不好,或者粗心大意,就是一盤垃圾。”“:)好,那再想想,老麥老肯他們的產品,味道是由什麼決定的?”“我知道,那是由他們的工作流程決定的,由於他們制定了非常規范的工作流程,原料放多少,加熱幾分鐘,都有嚴格規定,估計放多少鹽都是用克來計量的。而這個工作流程是在所有的門店都必須要遵照執行的,所以我們吃到的東西不管在哪在什麼時候味道都一樣。這裡我們要吃的食物都依賴工作流程。”
於是大鳥出題讓小菜實現一個畫小人的程序。
建造小人第一版
#include <stdio.h>
class Graphics
{
public:
void DrawEllipse(int x1,int y1,int x2,int y2)
{
printf("DrawEllipse %d,%d,%d,%d ",x1,y1,x2,y2);
}
void DrawRectangle(int x1,int y1,int x2,int y2)
{
printf("DrawRectangle %d,%d,%d,%d ",x1,y1,x2,y2);
}
void DrawLine(int x1,int y1,int x2,int y2)
{
printf("DrawLine %d,%d,%d,%d ",x1,y1,x2,y2);
}
};
class PersonThinBuilder
{
public:
PersonThinBuilder(Graphics _g) : g(_g){}
void Build()
{
g.DrawEllipse(50,20,30,30);
g.DrawRectangle(60,50,10,50);
g.DrawLine(60,50,40,100);
g.DrawLine(70,50,90,100);
g.DrawLine(60,100,45,150);
g.DrawLine(70,100,85,150);
}
protected:
Graphics g;
};
class PersonFatBuilder
{
public:
PersonFatBuilder(Graphics _g) : g(_g){}
void Build()
{
g.DrawEllipse(50,20,30,30);
g.DrawEllipse(60,50,10,50);
g.DrawLine(60,50,40,100);
g.DrawLine(70,50,90,100);
g.DrawLine(60,100,45,150);
g.DrawLine(70,100,85,150);
}
protected:
Graphics g;
};
int main()
{
Graphics gThin,gFat;
PersonThinBuilder* ptb = new PersonThinBuilder(gThin);
ptb->Build();
PersonFatBuilder* pfb = new PersonFatBuilder(gFat);
pfb->Build();
delete ptb;
delete pfb;
return 0;
}
“炒面忘記放鹽的問題依然沒有解決。比如我們現在需要你加一個高個的小人,你會不會因為編程不注意,又讓他缺胳膊少腿呢?”
“是呀,最好的辦法是規定,凡是建造小人,都必須要有頭和身體,以及兩收兩腳。”
建造者模式
將產品的內部表象和產品的生成過程分割開來,從而使一個建造過程生成具有不同的內部表象的產品對象。建造模式使得產品內部表象可以獨立的變化,客戶不必知道產品內部組成的細節。建造模式可以強制實行一種分步驟進行的建造過程。
實現方式(UML類圖)
實現代碼
#include <stdio.h>
class Graphics
{
public:
void DrawEllipse(int x1,int y1,int x2,int y2)
{
printf("DrawEllipse %d,%d,%d,%d ",x1,y1,x2,y2);
}
void DrawRectangle(int x1,int y1,int x2,int y2)
{
printf("DrawRectangle %d,%d,%d,%d ",x1,y1,x2,y2);
}
void DrawLine(int x1,int y1,int x2,int y2)
{
printf("DrawLine %d,%d,%d,%d ",x1,y1,x2,y2);
}
};
class PersonBuilder
{
public:
PersonBuilder(Graphics _g) : g(_g){}
virtual void BuildHead()=0;
virtual void BuildBody()=0;
virtual void BuildArmLeft()=0;
virtual void BuildArmRight()=0;
virtual void BuildLegLeft()=0;
virtual void BuildLegRight()=0;
protected:
Graphics g;
};
class PersonThinBuilder : public PersonBuilder
{
public:
PersonThinBuilder(Graphics g) : PersonBuilder(g){}
virtual void BuildHead()
{
g.DrawEllipse(50,20,30,30);
&n