设计模式--Builder模式
一、什么是Builder模式
Builder模式的定义:将一个复杂的对象的构建和其部件分离,将耦合度降到最低的一种设计模式。通俗的说,某个对象在创建过程中会设置很多的属性(很重要),需要一步一步的堆砌,为了把这个复杂的堆砌过程和自身每个属性设置解耦,可以单独设置某个属性,(如创建一台电脑,具有win系统,微型主板,inter内存,杂牌硬盘等属性,创建过程为:new computer,然后set各种属性)这种设计的模式就是builder模式,也就是将复杂模型对象的创建,和部件的表示分离。
二、代码结构实现Builder模式
在builder模式中,比较关键的点是builder的对象能够不断的设置产品的属性,因为产品的创建,与产品的属性配置是分离的,也就是说不能在产品的构造函数初始化所有,builder需要时刻占有对产品对象的修改权限,要做到这点,builder对象需要get到产品对象的地址,这点很关键。代码过程如下:
抽象产品类、和具体产品类:
很常规,产品类有三个属性,构造函数保护起来,添加友元,不理解这样做法的请看单例、工厂方法等模式的说明
class abstracProduct
{
public:
virtual ~abstracProduct() {};
virtual void setPartA() = 0;
virtual void setPartB() = 0;
virtual void setPartC() = 0;
};
class Product :public abstracProduct
{
public:
void setPartA() {};
void setPartB() {};
void setPartC() {};
private:
Product() = default;
string mPartA;
string mPartB;
string mPartC;
friend class Builder;
};
Builder类的编码:
由具体builder类创建具体产品类,并持有产品类对象用于后续的属性修改(根据自己的设计要求来获取到这个指针也可以,如单例模式等,根据个人爱好),在为每个属性修改时直接对产品执行相应修改即可。
class Product;
class abstracProduct;
class abstractBuilder
{
public:
virtual~abstractBuilder() {};
virtual abstracProduct*CreateProduct()=0;
};
class Builder :public abstractBuilder
{
public:
abstracProduct*CreateProduct()
{
mProductInstance = new Product;
return mProductInstance;
};
void setPartA() { mProductInstance->setPartA(); };
void setPartB() { mProductInstance->setPartB(); };
void setPartC() { mProductInstance->setPartC(); };
private:
abstracProduct*mProductInstance;
};
三、代码实现的注意事项
1、产品类的构造函数的保护
2、产品类对builder的友元声明
3、builder持有产品的实例句柄
4、当修改产品属性时,通过builder内部调用
5、builder的成员方法和产品的成员方法一一对应(不要求完全一致)
四、Builder模式的使用方法
在实际开发过程中,builder模式应用还是很广泛的,现已一个简单的例子演示过程
描述:假设要搭建一台电脑,需要很多部件,如主板、系统、显示器等(为简单只选择一小部分属性),在创建这台电脑对象和部件的分离表示过程如下:
定义产品类
class CComputer
{
public:
virtual void setBoard(string board)=0;
virtual void setOS(string os)=0;
virtual void setDisplay(string display)=0;
void ShowComputer();
protected:
CComputer();
string mBoard;
string mOS;
string mDisplay;
};
class MacBook:public CComputer
{
public:
MacBook();
public:
void setBoard(string board);
void setOS(string os);
void setDisplay(string display);
};
builder部分代码
class CComputer;
class CBuilder
{
public:
virtual void buildBoard(string board) = 0;
virtual void buildOS(string os) = 0;
virtual void buildDisplay(string display) = 0;
virtual CComputer*CreateComputer()=0;
virtual~CBuilder();
protected:
CBuilder();
};
class MacBuilder :public CBuilder
{
public:
void buildBoard(string board);
void buildOS(string os);
void buildDisplay(string display);
CComputer*CreateComputer();
MacBuilder();
CComputer*mMac;
};
MacBuilder::MacBuilder()
{
mMac = new MacBook;
}
void MacBuilder::buildBoard(string board)
{
mMac->setBoard(board);
}
void MacBuilder::buildOS(string os)
{
mMac->setOS(os);
}
void MacBuilder::buildDisplay(string display)
{
mMac->setDisplay(display);
}
CComputer*MacBuilder::CreateComputer()
{
return mMac;
}
客户区代码
CBuilder *bulder = new MacBuilder;
bulder->buildBoard("微星");
bulder->buildOS("windows");
bulder->buildDisplay("dell");
CComputer*computer = bulder->CreateComputer();
五、优缺点
优点:客户端不必知道产品内部组成的细节,属性和产品创建解耦,相同过程可以产生不同产品;具体的builder相互独立,不同的builder产生不同的产品;更加精细的控制产品;系统拓展方便;
缺点:代码量增加,如属性设置,添加一倍工作量;当属性多时容易遗忘builder相对于的添加该属性方法;