您的位置:首页 > 产品设计 > UI/UE

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

2015-01-29 14:46 363 查看


一、简介

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)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: