23种设计模式之四(创建型模式)Builder模式

一、简介

        Builder 模式要解决的是:当要创建的对象很复杂的时候(通常是由很多其他的对象组合而成),我们要把复杂对象的创建过程和这个对象的表示(展示)分离开来。样做的好处就是通过一步步的进行复杂对象的构建,由于在每一步的构造过程中可以引入参数,使得经过相同的步骤创建最后得到的对象的展示不一样。

           Builder设计模式,提供一种封装机制来隔离出构成复杂对象的各个子对象的变化,从而保持系统中的相对稳定的将这些子对象组合在一起的算法不随着需求的改变而改变。

        client通过Director对象提供的接口foodInfoPoint,一步步完成套餐的定制(BuildCoolDish、BuildDrink、BuildRice),进而得到不同的套餐种类,类Builder提供不同的封装接口,具体的实现在Product中。



二、详解

1、代码实现

(1)代码product.h:

#ifndef _PRODUCT_H_
#define _PRODUCT_H_
#include <vector>
#include <string>
#include <iostream>
using namespace std;

class ProductFood
{
    public:
        ProductFood();
        ~ProductFood();
        void addFood(string foodName,int price);
        void showFood();  
    protected:
    private:
    	  vector<string> mFoodName;  //食品名称
        vector<int> mPrice;        //食品价格
};

#endif
(2)代码product.cpp:

#include "product.h"

ProductFood::ProductFood()
{
	  mFoodName.clear();
	  mPrice.clear();
}

ProductFood::~ProductFood()
{
}

void ProductFood::addFood(string foodName,int price)
{
	  mFoodName.push_back(foodName);  
    mPrice.push_back(price);
}

void ProductFood::showFood()
{
	  int totalPrice = 0;
	  cout<<"------food list:------"<<endl; 
	  for(int i = 0; i < mFoodName.size(); ++i) {
	      totalPrice += mPrice[i];
	  	  cout<<mFoodName[i]<<" = "<<mPrice[i]<<" yuan"<<endl; 
	  }
	  cout<<"******total = "<<totalPrice<<" yuan"<<endl;
}
(3)代码builder.h:
#ifndef _BUILDER_H_
#define _BUILDER_H_
#include <string>
using namespace std;

class ProductFood;
class Builder    //定义抽象的制作类,含有三个制作的环节和一个返回制作出来的产品方法
{
    public:
         virtual ~Builder();
         virtual void BuildCoolDish(const string &buildPara) = 0;
         virtual void BuildDrink(const string &buildPara) = 0;
         virtual void BuildRice(const string &buildPara) = 0;
         virtual ProductFood *GetProductPoint() = 0;
    protected:
        Builder();
        ProductFood *food;
    private:
};

class ConcreteBuilder1 : public Builder
{
    public:
        ConcreteBuilder1();
        ~ConcreteBuilder1();
        void BuildCoolDish(const string &buildPara);
        void BuildDrink(const string &buildPara);
        void BuildRice(const string &buildPara);
        ProductFood *GetProductPoint();
    protected:
    private:
};

class ConcreteBuilder2 : public Builder
{
    public:
        ConcreteBuilder2();
        ~ConcreteBuilder2();
        void BuildCoolDish(const string &buildPara);
        void BuildDrink(const string &buildPara);
        void BuildRice(const string &buildPara);
        ProductFood *GetProductPoint();
    protected:
    private:
};

#endif
(4)代码builder.cpp:
#include <iostream>
#include "builder.h"
#include "product.h"
using namespace std;

Builder::Builder()
{
	  food = NULL;
}

Builder::~Builder()
{
	    if (food) {
	        delete food;
	        food = NULL;
	    }
}

ConcreteBuilder1::ConcreteBuilder1()
{
	    food = new ProductFood();
}

ConcreteBuilder1::~ConcreteBuilder1()
{
}
//套餐A,凉菜收10,饮料11,拉面12,总共33元
void ConcreteBuilder1::BuildCoolDish(const string &buildPara)
{
	cout<<"A:CoolDish have finished"<<endl;
	food->addFood(buildPara, 10);
}

void ConcreteBuilder1::BuildDrink(const string &buildPara)
{
    cout<<"A:Drink have finished"<<endl;
	  food->addFood(buildPara, 11);
}

void ConcreteBuilder1::BuildRice(const string &buildPara)
{
    cout<<"A:Rice have finished"<<endl;
	  food->addFood(buildPara, 12);
}

ProductFood *ConcreteBuilder1::GetProductPoint()
{
    return food;
}

ConcreteBuilder2::ConcreteBuilder2()
{
	  food = new ProductFood();
}

ConcreteBuilder2::~ConcreteBuilder2()
{
}
//套餐B,凉菜收20,饮料21,拉面22,总共63元
void ConcreteBuilder2::BuildCoolDish(const string &buildPara)
{
    cout<<"B:CoolDish have finished"<<endl;
	  food->addFood(buildPara, 20);
}

void ConcreteBuilder2::BuildDrink(const string &buildPara)
{
    cout<<"B:Drink have finished"<<endl;
	  food->addFood(buildPara, 21);
}

void ConcreteBuilder2::BuildRice(const string &buildPara)
{
    cout<<"B:Rice have finished"<<endl;
	  food->addFood(buildPara, 22);
}

ProductFood *ConcreteBuilder2::GetProductPoint()
{
    return food;
}
(5)代码director.h:
#ifndef _DIRECTOR_H_
#define _DIRECTOR_H_

class Builder;
class ProductFood;
class Director      //指导者,担任这个角色的类调用具体建造者角色以创建产品对象。此处是收银员
{
    public:
        Director();
        ~Director();
        ProductFood *foodInfoPoint(char ch);
    protected:
    private:
        Builder *_bld;
};

#endif
(6)代码director.cpp:
#include "director.h"
#include "builder.h"
#include "product.h"

Director::Director()
{
	 _bld = NULL;
}

Director::~Director()
{
	  if (_bld) {
	       delete _bld;
	       _bld = NULL;
	   }
}

ProductFood *Director:: foodInfoPoint(char ch)
{
	   if (_bld) {
	       delete _bld;
	       _bld = NULL;
	   }
     if(ch == 'A') {
         _bld = new ConcreteBuilder1();
     } 
     else if(ch == 'B') {
   	     _bld = new ConcreteBuilder2();
   	 } 
     else {    //other
     }
    _bld->BuildCoolDish("CoolDish");
    _bld->BuildDrink("Drink");
    _bld->BuildRice("Rice");
    return _bld->GetProductPoint();
}
(7)代码main.cpp:
#include <iostream>
#include "builder.h"
#include "product.h"
#include "director.h"
using namespace std;

int main()
{
    Director *dt = new Director();
    //根据需要客户端的需要传入
    char ch;
    //客户到来,输入需要哪种套餐A或B
    for(int i = 0; i < 2; i++) {
        cin>>ch;
        cout<<"-------------------"<<endl;
        dt->foodInfoPoint(ch)->showFood();
    }
    delete dt;
    return 0;
}
(8)makefile:
CFLAGS = -g
DEFINED = #-D _VERSION
LIBS = 
CC = g++
INCLUDES = -I./
OBJS= main.o product.o director.o builder.o
TARGET= main
all:$(TARGET)

$(TARGET):$(OBJS)
	$(CC) $(CFLAGS) -o $@ $(OBJS)

.SUFFIXES:.o .h
.SUFFIXES:.cpp .o
.cpp.o:
	$(CC) $(DEFINED) -c $(CFLAGS) -o $@ $<

ok:
	./$(TARGET)
clean:
	rm -f $(OBJS) $(TARGET) core *.log

2、运行结果

(centos6.3系统中运行结果:)


三、总结

(1) Builder 模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

(2)Builder 模式和 AbstractFactory 模式在功能上很相似,因为都是用来创建大的复杂的对象,它们的区别是:Builder 模式强调的是一步步创建对象,并通过相同的创建过程可以获得不同的结果对象,一般来说 Builder 模式中对象不是直接返回的。而在 AbstractFactory 模式中对象是直接返回的,AbstractFactory 模式强调的是为创建多个相互依赖的对象提供一个同一的接口。

(3)源码已经打包上传到csdn上可登录下载(http://download.csdn.net/detail/taiyang1987912/8407045)。 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Builder模式 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示 统设计中,有时候面临着一个“复杂系统”的创建工作,该对象通常由各个部分的子对象用一定的算法构成,或者说按一定的步骤组合而成;这些的算法和步骤是稳定的,而构成这个对象的子对象却经常由于需求改变而发生变化,此时我们可以选择使用Builder模式。尽管Builder模式相当容易让人误解,但我认为这几点应该是不会有错的。因此我个人认为Builder模式中要好好把握如下几点 1. 需要创建的对象是复杂对象 2. 对象的创建过程是一步步创建(即:可能由于过程的不同而导致有不同的对象展示) 3. 明确建造者(Builder)、具体建造者(Concrete Builder)、指导者(Director)、产品(Product)之间的职责和联系。 ◆建造者(Builder): 给出一个抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此接口独立于应用程序的商业逻辑。模式中直接创建产品对象的是 具体建造者(ConcreteBuilder):具体建造者类必须实现这个接口所要求的方法:一个是建造方法,另一个是结果返还方法。 ◆具体建造者(Concrete Builder): 担任这个角色的是于应用程序紧密相关的类,它们在应用程序调用下创建产品实例。这个角色主要完成的任务包括: ■实现Builder角色提供的接口,一步一步完成创建产品实例的过程。 ■在建造过程完成后,提供产品的实例。 ◆指导者(Director): 担任这个角色的类调用具体建造者角色以创建产品对象。导演者并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者对象。 ◆产品(Product): 产品便是建造中的复杂对象。 详细见博客 http://blog.csdn.net/xiaoting451292510/article/details/8330462

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乌托邦2号

博文不易,支持的请给予小小打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值