阿Sam的设计模式学习笔记---- Builder模式

来源:互联网 发布:js如何给标签添加属性 编辑:程序博客网 时间:2024/05/17 12:54
1, 功能:将一个功能复杂的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
2, 基本思想:
通常一个复杂的对象由各个部分组成,有时可能因为客户需求,版本升级等原因,各个部分内部不停的发生变化,但是将它们组装成一起的方法相对固定。Builder模式将产品内部状态和生产过程分割,同一个生产过程可以生产出内部具有不同表象的产品。
Builder模式的根本目的就是解耦过程和部件。
一个Product是一个复杂的产品,它由很多部分组成。为了能生产“不同表象”的产品,需要一个Builder提供抽象接口,并由ConcreteBuilder实现这些接口并装备Product的各个部分。最后Director来使用Builder接口方法(通过ConcreteBuilder对接口的多态实现)来构造并获得生产出来的复杂产品。
具体每个部件的创建是由ConcreteBuilder完成的,一个ConcreteBuilder会生产出所需的所有部件,组装过程是由Director调用Builder对象的接口来实现的。
3, 适用情况:
  • 创建复杂对象的算法应独立于该对象的组成部分以及它们的装配方式;
  • 构造过程需要构造出具有不同表象的对象。
4, 结构:
Class Diagram
Sequence Diagram
5, 代码示例:
本人是吃移动通信这碗饭的,资质愚钝,目光短浅,只能举一下这方面的例子了。中国移动是运营商(Carrier),现在他想在上海和四川建立两个无线网络。为了简化例子,网络中的网元只有BSCBTSMSC。每个网元的产品可能会变化,但是这些网元组装在一起的方式不会变,运营商都必须要有这些设备来组成网络。
A.网络(Network)是一个复杂对象,就是我们要组建的Product
class Network  // Builder
{
public:
    
void addBSC(const char *bsc) { if(bsc) strcpy(BSC, bsc); }
    
void addBTS(const char *bts) { if(bts) strcpy(BTS, bts); }
    
void addMSC(const char *msc) { if(msc) strcpy(MSC, msc); }    
    
void showNet() {cout << "The network in this place: BSC ==> " << BSC << " || BTS ==> " << BTS << " || MSC ==> " << MSC << endl;}
private:
    
char BSC[15];    
    
char BTS[15];    
    
char MSC[15];
};
B. Builder模式中的Builder提供构造各个部分的接口,以及返回产品的接口,每个接口的具体实现放在子类。各个ConcreteBuilder根据自己所需构造各个部分,并且实现返回Product的接口。本例中,Builder就是设备提供商(Provider),他们来为运营商提供网络的各个部分。
class Network  // Builder
{
public:
    
void addBSC(const char *bsc) { if(bsc) strcpy(BSC, bsc); }
    
void addBTS(const char *bts) { if(bts) strcpy(BTS, bts); }
    
void addMSC(const char *msc) { if(msc) strcpy(MSC, msc); }    
    
void showNet() {cout << "The network in this place: BSC ==> " << BSC << " || BTS ==> " << BTS << " || MSC ==> " << MSC << endl;}
private:
    
char BSC[15];    
    
char BTS[15];    
    
char MSC[15];
};

class Provider  //Builder, 设备提供商
{
public:
     virtual 
void buildBSC() = 0;    
     virtual 
void buildBTS() = 0;    
     virtual 
void buildMSC() = 0;    
     virtual Network getNetwork() 
= 0;
}; 
class Ericsson: public Provider  // ConcreteBuilder, 一个具体的设备提供商
{
public:
    Ericsson();    
    
~Ericsson(){}    
    
void buildBSC() {mobileNet.addBSC("Ericsson BSC");}    
    
void buildBTS() {mobileNet.addBTS("Ericsson BTS");}    
    
void buildMSC() {mobileNet.addMSC("Ericsson MSC");}    
    Network getNetwork() {
return mobileNet;}private:    
    Network mobileNet;
}; 
Ericsson::Ericsson()
{
    mobileNet.addBSC(
"NULL");    
    mobileNet.addBTS(
"NULL");    
    mobileNet.addMSC(
"NULL");


class Alcatel: public Provider  // ConcreteBuilder, 一个具体的设备提供商
{
public:
    Alcatel();    
    
~Alcatel(){}    
    
void buildBSC() {mobileNet.addBSC("Alcatel BSC");}    
    
void buildBTS() {mobileNet.addBTS("Alcatel BTS");}    
    
void buildMSC() {mobileNet.addMSC("Alcatel MSC");}    
    Network getNetwork() {
return mobileNet;}
private:
    Network mobileNet;
}; 
Alcatel::Alcatel()
{
    mobileNet.addBSC(
"NULL");    
    mobileNet.addBTS(
"NULL");    
    mobileNet.addMSC(
"NULL");
}
C. Director来负责实现实际的组装工作. Director实际上调用Builder对象的成员来组装产品,最后还是通过Builder对象提供的得到产品的接口来得到最后组装的产品。本例中,运营商就是Director对象,他通过与他签订合同(传递参数)的设备商(Provider)来建立网络(Product)。
class Carrier  // Director
{
public:
    
void constructer(Provider * devProvider);
};
void Carrier::constructer(Provider * devProvider)
{
    devProvider
->buildBSC();
    devProvider
->buildBTS();
    devProvider
->buildMSC();
}
D.在客户端为上海和四川建立网络了。
int main()
{
    Carrier CMCC; 
//中国移动是一个运营商,是Director对象
 
    Provider 
* devProvider1 = new Ericsson(); //定义一个ConcreteBuilder
    Provider * devProvider2 = new Alcatel();   //又一个ConcreteBuilder
 
    CMCC.constructer(devProvider1); 
//移动用Ericsson的设备在上海建网
    Network ShanghaiNet = devProvider1->getNetwork();
    ShanghaiNet.showNet();
 
    CMCC.constructer(devProvider2); 
//运营商用Alcatel的设备在四川建网。
    Network SichuanNet = devProvider2->getNetwork();
    SichuanNet.showNet();
 
    delete devProvider1;
    delete devProvider2;
 
    
return 0;
}
回顾一下上面的例子,运营商要建立一个网络:
  • 网络就是Product.
  • Builder对应构建网络的各个部分(BSCBTSMSC)。
  • ConcreteBuilder就是具体的设备商,有EricssonAlcatel
  • Director就是运营商CMCC,它使用不同的设备提供商来建网。
6, 总结:
1)       Builder模式用于“分步骤构建一个复杂的对象”,在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分经常变化。
2)       产品通常不需要抽象类,因为我们强调的是生成复杂的产品的过程相对稳定,复杂对象的各部分变化较大,而且这些个部分不一定有相同的父类,所以不需要产品的抽象类。
3)       比较一下Simple FactoryAbstractor FactoryFactory MethodBuilder模式
A. 生成简单对象的情况,使用Simple Factory即可;
B. 需要生成复杂对象的情况,使用Builder模式。进一步优化,可以让Builder负责生成复杂对象,复杂对象的各部分的生成可以用Simple Factory来实现。
C. 如果系统发展壮大,导致需要许多的Builder来构造许多复杂对象,这是就需要用Abstract Factory生成一系列的Builder,以对复杂对象的生成进行系统管理;
D.Factory Method可以用于更大的系统,让基本功能在父类中实现,具体的对象生成由子类完成,可以使用其它三种方式配合完成具体对象的产生。
 
 
原创粉丝点击