设计模式 创建者模式
设计模式 创建者模式
- 前言
- 原来代码
- 使用设计模式
- 总结
- Builder模式在源码中的应用:
- 其他代码
前言
-
“对象创建”模式——绕开new
工厂模式 抽象工厂 原型模式 构建器
-
动机与背景
目前需要建造一个房子,建造房子需要一系列特定的步骤,但是房子的类型也有很多,不同类型的房子对应的建造步骤也不尽相同。
用于分步骤构建对象 -
没有使用设计模式的代码
// 可以参照模板方法
-
存在的问题
个人感觉与模板方式很相似,所以上面的代码使用了模板方法的代码
-
解决方法
使用构建器,将复杂多变的对象的构建过程抽象出来
-
使用设计模式的代码
原来代码
Builder 模式主要用于“分步骤构建一个复杂的对象”。
在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。
变化点在哪里,封装哪里—— Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。
其缺点在于难以应对“分步骤构建算法”的需求变动。在Builder模式中,要注意不同语言中构造器内调用虚函数的差别(C++ vs. C#) 。
//原来的代码
class House{
protected:
void init(){ //1.构建的流程是稳定的
this -> BuildPart1(); // 打地基
for(int i = 0 ; i < 4 ; i ++){
this -> BuildPart2();
}
bool flag = this -> BuildPart3();
if(flag){
this -> BuildPart4();
}
this -> BuildPart5();
}
virtual ~House(){}
//代表建房子的门 窗户 等 ,2.构建的方法是变化的,纯虚函数
virtual void BuildPart1() = 0;
virtual void BuildPart2() = 0;
virtual void BuildPart3() = 0;
virtual void BuildPart4() = 0;
virtual void BuildPart5() = 0;
};
在这里有个问题是,能不能把init函数名替换成构造函数:不能,C++构造函数是静态绑定
class StoneHose:public House{
protected: //实例化
virtual void BuildPart1(){...............}
virtual void BuildPart2(){...............}
virtual void BuildPart3(){...............}
virtual void BuildPart4(){...............}
virtual void BuildPart5(){...............}
};
到这里已经完成了,使用:
int main()
{
//就是父类指针指向子类对象
House * pHouse = new StoneHose();
pHouse ->Init();
}
使用设计模式
//把上面的代码,用设计模式
//如果对象比较复杂,可以做如下拆分,把House分成两个,一个是定义方法(可变)的叫做HouseBuilder ,一个定义流程、逻辑的是把init放进去
class House{
//........
void Part1();
void Part2();
void Part3();
};
class HouseBuilder{
public:
House *GetResult() {
return pHouse;
}
virtual ~HouseBuilder(){}
protected:
//代表建房子的门 窗户 等 ,2.构建的方法是变化的,纯虚函数
virtual void BuildPart1() = 0;
virtual void BuildPart2() = 0;
virtual void BuildPart3() = 0;
virtual void BuildPart4() = 0;
virtual void BuildPart5() = 0;
};
//塞一个 HouseBulider指针,把 this 换成pHouseBuilder
class HouseDirector{
public:
HouseBulider *pHouseBuilder;
//另外要加入构造函数
HouseDirector(HouseBulider *pH){ //新加入
this -> pHouseBuilder = pH;
}
HouseBulider Construct(){//void init() 构建过程,不是虚函数
pHouseBuilder -> BuildPart1(); // 打地基
for(int i = 0 ; i < 4 ; i ++){
pHouseBuilder -> BuildPart2();//把init()中的 this 换成pHouseBuilder
}
bool flag = pHouseBuilder -> BuildPart3();
if(flag){
pHouseBuilder -> BuildPart4();
}
pHouseBuilder -> BuildPart5();
return pHouseBuilder->GetResult();
}
}
//那么石头房子呢 StoneHose:public House 感觉这里是不需要呀 看这个https://zhuanlan.zhihu.com/p/665141864
class StoneHose:public House{ //对象的表示
};
class StoneHoseBuilder:public HouseBuilder{ // 实现
protected:
virtual void BuildPart1(){...............}
virtual void BuildPart2(){...............}
virtual void BuildPart3(){...............}
virtual void BuildPart4(){...............}
virtual void BuildPart5(){...............}
};
void main() {
StoneHouseBuilder *pStoneHouseBuilder = new StoneHouseBuilder;
HouseDirector *pHouseDirector = new HouseDirector(HouseBuilder *pStoneHouseBuilder);
pHouseDirector->Construct();
// 操作
}
构建过程太复杂,抽象出来单独变成类
把对象的表示和构建相分离,(House 和 HouseBuilder),是的同样的构建(稳定)过程(Construct)可以构建不同的表示(变化)
上面只是一个演化模式,
总结
总结一下,就是把一个有构建步骤的对象拆分,分成表示和实现方法过程,实现过程稳定(不抽象),表示部分可以抽象,用虚函数实现
class A{//需要创建的事物、对象,这里定义A的组成
set_Part1();
}
class B_builer (方法接口){ //A的组成实现接口,要有能返回A的接口
//1.要拥有A指针成员 A *m_a
//2.要拥有构造函数,传入A,实现多态 B_builer(A a){this->m_a = a;}
//3.要有返回A 的方法接口 A GetComputer()
//4.要定义建造A需要的方法接口:buildPart1 2 3 4 …
A *m_a ;
B_builer(A *a){this->m_a = a;}
virtual buildPart1() = 0;
virtual A* GetComputer() = 0; // 要有返回A 的方法接口
};
class B_concrete_builer (方法实现):public B_builer{
virtual buildPart1(){ this -> A->setPart1();} //具体实现
virtual A* GetComputer(){return tbis->A ;}; // 具体实现 要有返回A 的方法接口
};
class C_Process (稳定的构建过程)
{
//1.要拥有建造(材料)的方法接口的指针成员 B_builer *m_b_builer
B_builer *m_b_builer ;
//2.要拥有构造函数,传入B_builer,实现多态
C_Process(B_builer *b_builer){this->m_b_builer = b_builer;}
//2,稳定的构建过程代码(建造逻辑) ,要返回A
A *func(){
step 1 2 3 …
return m_b_builer->GetResult();
}
}
使用过程:
B_concrete_builer *B = new B_concrete_builer();
C_Process *C = new C_Process(B);
C->func();
A = B->GetComputer();
Builder模式在源码中的应用:
StringBuilder
其实我们熟知的StringBuilder就是builder模式的典型实现。我们平时使用基本都是这样:
1 StringBuilder sb = new StringBuilder();
2 sb.append(123).append(‘a’)
3 .append(1.23)
4 .append(true)
5 .append(“hhhh”);
https://zhuanlan.zhihu.com/p/113971558
其他代码
这个很好:
https://zhuanlan.zhihu.com/p/665141864
//下面是源码
#include <iostream>
using namespace std;
#include <string>
//需要的产品:笔记本电脑
class Computer {
public:
void SetCPU(const string cpu) {
this->cpu = cpu;
}
void SetDisk(const string disk) {
this->disk = disk;
}
void SetMemory(const string memory) {
this->memory = memory;
}
void SetScreen(const string screen) {
this->screen = screen;
}
void ShowInfo() {
cout << "======基本信息======" << endl;
cout << this->cpu << endl;
cout << this->memory << endl;
cout << this->disk << endl;
cout << this->screen << endl;
cout << "====================" << endl;
}
private:
string cpu; //CPU
string disk; //磁盘
string memory; //内存
string screen; //显示屏
};
//抽象的建造者:抽象建造单位
class Builder
{
public:
virtual void BuilderCpu() = 0; //建造CPU
virtual void BuilderMemory() = 0; //建造内存
virtual void BuilderDisk() = 0; //建造磁盘
virtual void BuilderScreen() = 0; //建造显示屏
virtual Computer* GetComputer() = 0; //出厂建造好的笔记本
};
//具体的建造者:具体施工单位、具体的建造方式
class DellBuilder : public Builder //dell笔记本
{
private:
Computer* computer;
public:
DellBuilder() {
this->computer = new Computer();
}
void BuilderCpu() {
this->computer->SetCPU("DELL CPU");
}
void BuilderMemory() {
this->computer->SetMemory("DELL 内存");
}
void BuilderDisk() {
this->computer->SetDisk("Dell 磁盘");
}
void BuilderScreen() {
this->computer->SetScreen("DELL 显示屏");
}
Computer* GetComputer()
{
return this->computer;
}
};
//具体的建造者:具体施工单位、具体的建造方式
class AppleBuilder : public Builder //dell笔记本
{
private:
Computer* computer;
public:
AppleBuilder() {
this->computer = new Computer();
}
void BuilderCpu() {
this->computer->SetCPU("Apple CPU");
}
void BuilderMemory() {
this->computer->SetMemory("Apple 内存");
}
void BuilderDisk() {
this->computer->SetDisk("Apple 磁盘");
}
void BuilderScreen() {
this->computer->SetScreen("Apple 显示屏");
}
Computer* GetComputer()
{
return this->computer;
}
};
//指导者:指挥具体的建造逻辑
class Director
{
public:
Director(Builder* builder) {
this->builder = builder;
}
//建造逻辑
void BuilderComputer() {
//1.建造CPU
this->builder->BuilderCpu();
cout << "first make cpu" << endl;
//2.建造内存条
this->builder->BuilderMemory();
cout << "second make memory" << endl;
//3.建造磁盘
this->builder->BuilderDisk();
cout << "third make disk" << endl;
//4.建造显示屏
this->builder->BuilderScreen();
cout << "finally, make screen" << endl;
}
private:
Builder* builder;
};
//客户端
int main()
{
Computer* computer = NULL;
Builder* builder = NULL;
Director* director = NULL;
//需求:要一台dell笔记本
builder = new DellBuilder(); // 先找一个dell制造厂,负责具体的创建
director = new Director(builder); //指导者,指导Dell制造厂如何创建
director->BuilderComputer(); //开始创建了。。。
computer = builder->GetComputer(); // 待建造完毕,制造厂出货
computer->ShowInfo(); //产品质检合格
delete computer;
delete director;
delete builder;
//制造Aplle比较笔记本,同理可得。
return 0;
}