建造者模式——Builder

前序

小菜和大鸟两人出去吃夜宵,大鸟要了份炒饭,小菜要了份炒面。炒完后大鸟看到炒面感觉不错,于是也叫了一份。大鸟尝后感觉淡而无味,于是便问小菜:“为什么你的炒面好吃,而我再要的炒面却没有放盐?这好吃不好吃是由谁决定的?”小菜答道:“当然是烧菜的人,他感觉好,就是一盘好面,要是心情不好,或者粗心大意,就是一盘垃圾。”“:)好,那再想想,老麦老肯他们的产品,味道是由什么决定的?”“我知道,那是由他们的工作流程决定的,由于他们制定了非常规范的工作流程,原料放多少,加热几分钟,都有严格规定,估计放多少盐都是用克来计量的。而这个工作流程是在所有的门店都必须要遵照执行的,所以我们吃到的东西不管在哪在什么时候味道都一样。这里我们要吃的食物都依赖工作流程。”

于是大鸟出题让小菜实现一个画小人的程序。

建造小人第一版

#include <stdio.h>
 
class Graphics
{
public:
       void DrawEllipse(int x1,int y1,int x2,int y2)
       {
              printf("DrawEllipse %d,%d,%d,%d\n",x1,y1,x2,y2);
       }
      
       void DrawRectangle(int x1,int y1,int x2,int y2)
       {
              printf("DrawRectangle %d,%d,%d,%d\n",x1,y1,x2,y2);
       }
      
       void DrawLine(int x1,int y1,int x2,int y2)
       {
              printf("DrawLine %d,%d,%d,%d\n",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\n",x1,y1,x2,y2);
       }
      
       void DrawRectangle(int x1,int y1,int x2,int y2)
       {
              printf("DrawRectangle %d,%d,%d,%d\n",x1,y1,x2,y2);
       }
      
       void DrawLine(int x1,int y1,int x2,int y2)
       {
              printf("DrawLine %d,%d,%d,%d\n",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);
       }
      
       virtual void BuildBody()
       {
              g.DrawRectangle(60,50,10,50);
       }
      
       virtual void BuildArmLeft()
       {
              g.DrawLine(60,50,40,100);
       }
      
       virtual void BuildArmRight()
       {
              g.DrawLine(70,50,90,100);
       }
      
       virtual void BuildLegLeft()
       {
              g.DrawLine(60,100,45,150);
       }
      
       virtual void BuildLegRight()
       {
              g.DrawLine(70,100,85,150);
       }
};
 
class PersonFatBuilder : public PersonBuilder
{
public:
       PersonFatBuilder(Graphics g) : PersonBuilder(g){}
      
       virtual void BuildHead()
       {
              g.DrawEllipse(50,20,30,30);
       }
      
       virtual void BuildBody()
       {
              g.DrawEllipse(60,50,10,50);
       }
      
       virtual void BuildArmLeft()
       {
              g.DrawLine(60,50,40,100);
       }
      
       virtual void BuildArmRight()
       {
              g.DrawLine(70,50,90,100);
       }
      
       virtual void BuildLegLeft()
       {
              g.DrawLine(60,100,45,150);
       }
      
       virtual void BuildLegRight()
       {
              g.DrawLine(70,100,85,150);
       }
};
 
class PersonDirector
{
public:
       PersonDirector(PersonBuilder* _pb) : pb(_pb){}
      
       void CreatePerson()
       {
              pb->BuildHead();
              pb->BuildBody();
              pb->BuildArmLeft();
              pb->BuildArmRight();
              pb->BuildLegLeft();
              pb->BuildLegRight();
       }
protected:
       PersonBuilder* pb;
};
 
int main()
{
       Graphics gThin,gFat;
      
       PersonThinBuilder* ptb = new PersonThinBuilder(gThin);
       PersonDirector* pdThin = new PersonDirector(ptb);
       pdThin->CreatePerson();
      
       PersonFatBuilder* pfb = new PersonFatBuilder(gFat);
       PersonDirector* pdFat = new PersonDirector(pfb);
       pdFat->CreatePerson();
      
       delete ptb;
       delete pdThin;
       delete pfb;
       delete pdFat;
       return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值