当前位置: 首页 > article >正文

设计模式 创建者模式

设计模式 创建者模式

  • 前言
  • 原来代码
  • 使用设计模式
  • 总结
  • Builder模式在源码中的应用:
  • 其他代码

前言

  1. “对象创建”模式——绕开new

    工厂模式 抽象工厂 原型模式 构建器

  2. 动机与背景

    目前需要建造一个房子,建造房子需要一系列特定的步骤,但是房子的类型也有很多,不同类型的房子对应的建造步骤也不尽相同。
    用于分步骤构建对象

  3. 没有使用设计模式的代码

// 可以参照模板方法

  1. 存在的问题

    个人感觉与模板方式很相似,所以上面的代码使用了模板方法的代码

  2. 解决方法

    使用构建器,将复杂多变的对象的构建过程抽象出来

  3. 使用设计模式的代码

原来代码

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 StoneHosepublic 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 StoneHosepublic House{  //对象的表示

}class StoneHoseBuilderpublic 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;
}

http://www.kler.cn/a/154040.html

相关文章:

  • ### 哋它亢在5G基站中的应用:新兴技术与未来通信的融合
  • urdf笔记
  • 通过华为鲲鹏认证发行上市的集成平台产品推荐
  • STM32串口——5个串口的使用方法
  • SpringBoot Data Redis连接Redis-Cluster集群
  • 极速入门数模电路
  • 今天给大家分享一套Python入门基础测试题,大家看看都会做吗?
  • 商城系统通过Kafka消息队列,实现订单的处理和状态更新
  • 快速掌握Pyqt5的9种显示控件
  • 2243:Knight Moves
  • postman接口测试教程与实例分享
  • mysql查询用户每年每月的订单数量及订单金额
  • 解决Flutter报错boxconstraints has non-normalized height/width constraints
  • 设计模式-结构型模式之组合、享元设计模式
  • 最长连续递增序列
  • [学习记录]Node event loop 总结流程图
  • STL--位图的介绍与使用
  • 以热爱的态度对待生活,就是最自己的温柔
  • 软著项目推荐 深度学习疲劳驾驶检测 opencv python
  • 线程的状态
  • 详解原生Spring框架下的方法切入点表达式
  • 【IEEE出版|往届均已成功EI检索】2024年第四届消费电子与计算机工程国际学术会议(ICCECE 2024)
  • 智慧工地一体化解决方案(里程碑管理)源码
  • 背包9讲系列2-完全背包问题
  • 《论文阅读》DualGATs:用于对话中情绪识别的双图注意力网络
  • 正确理解MySQL的MVCC及实现原理