设计模式 创建者模式

设计模式 创建者模式

  • 前言
  • 原来代码
  • 使用设计模式
  • 总结
  • 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; //CPUstring disk; //磁盘string memory; //内存string screen; //显示屏
};//抽象的建造者:抽象建造单位
class Builder
{
public:virtual void BuilderCpu() = 0; //建造CPUvirtual 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.建造CPUthis->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.mzph.cn/news/177740.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ansys Lumerical|带 1D-2D 光栅的出瞳扩展器

附件下载 联系工作人员获取附件 此示例显示了设置和模拟出瞳扩展器 &#xff08;EPE&#xff09; 的工作流程&#xff0c;EPE 是波导型增强现实 &#xff08;AR&#xff09; 设备的重要组成部分。该工作流程将利用 Lumerical 和 Zemax OpticStudio 之间的动态链接功能 。为了…

以促进产教融合、协同育人等方式,优路教育发挥职教价值

开展校企合作&#xff0c;推动产教融合&#xff0c;一直是优路教育推进职业教育高质量发展的重要举措&#xff0c;亦是响应政策号召&#xff0c;发挥职教价值的重要实践。 据悉&#xff0c;优路教育积极响应教育部产学合作协同育人政策号召&#xff0c;与西安理工大学土木建筑工…

MySQL(主从复制)

简述&#xff1a;主从复制&#xff0c;是用来建立一个和主数据库完全一样的数据库环境&#xff0c;称为从数据库&#xff0c;主数据库一般是准实时的 业务数据库、事务处理库&#xff0c;从库做查询库。 复制过程简单的说就是 master 将数据库的改变写入二进制日志&#xff0c…

高噪点灰度图目标粗定位CoraseLocation

高噪点的灰度图目标粗定位 /* ** @name: CoraseLocation ** @brief: 粗定位 ** @param:[in] srcGray 灰度图() ** @param:[in] box 目标尺寸(像素) ** @param:[ou] roi 目标定位结果 ** @return: true=成功,false=失败 */ bool CoraseLocation(cv::Mat& s…

【Bootloader学习理解学习--加强版】

笔者在接着聊一下bootloader&#xff0c;主要针对MCU的Bootloader。 笔者之前介绍过一篇Bootloader文章&#xff0c;主要是其概念、一些升级包的格式和升级流程&#xff0c;本次接着来说一下。 1、MCU代码运行方式 之前文章也介绍过&#xff0c;MCU的代码运行方式有两种&…

水淼采集器-免费水淼采集器下载

在当今数字时代&#xff0c;随着信息的迅猛增长&#xff0c;许多网站管理员面临一个共同而具有挑战性的问题——如何在短时间内获取大量优质内容&#xff0c;以满足用户对信息的不断需求&#xff1f;水淼采集器&#xff0c;作为一个备受瞩目的解决方案&#xff0c;正成为许多人…

错误:FinalShell连接CentOs连接失败

需要说明的是:这个错误不是首次连接发生的,而是多次使用后可能发生的错误 正文: 可能的原因是虚拟机的ip地址发生了变更,原因有以下几点: 最最可能的原因:1.DHCP分配变更&#xff1a; 如果虚拟机使用DHCP来获取IP地址&#xff0c;那么DHCP服务器可能会分配给虚拟机一个新的I…

shell脚本正则表达式

目录 一. 正则表达式定义 二. 基本正则表达式 1. 元字符 2. 表示次数 3. 位置锚定 4. 分组或其他 二. 拓展正则表达式 1. 表示次数 2. 表示分组 一. 正则表达式定义 正则表达式&#xff08;REGEXP &#xff09;&#xff1a;由一类特殊字符及文本字符所编写的模式&…

常量指针和指针常量的区别

常量指针 常量指针&#xff0c;本质是指针&#xff0c;这个指针指向的内存块是常量&#xff0c;不能通过这个指针改变指向的内存块的值。 定义&#xff1a; const int *p; #include <iostream> using namespace std;int main(int argc, char *argv[]) {int a 10;int…

Logstash安装部署

目录 一、环境准备 二、安装部署 2.1 下载安装包到指定文件夹&#xff0c;并解压 2.2 复制证书文件 2.3 编辑配置文件 2.4 启动服务 一、环境准备 部署模式&#xff1a;单节点部署。 官网地址&#xff1a;Elasticsearch 平台 — 大规模查找实时答案 | Elastic 注意事项&am…

网站HTTPS证书

作为拥抱数字化时代的重要一环&#xff0c;建设一个安全可靠的网站对于吸引访问者并保持用户信任至关重要。在这方面&#xff0c;HTTPS证书是不可或缺的工具。HTTPS&#xff08;安全套接层传输协议&#xff09;证书是由受信任的第三方CA机构颁发的一种数字证书。它通过加密通信…

①实现基于session的登录流程:发送验证码、登录注册、校验登陆状态

个人简介&#xff1a;Java领域优质创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ 登录功能 实现 实现基于session的登录流程&…

制作openeuler的livecd

下载该项目&#xff0c;执行下面的操作gitee openeuler livecd项目 基于openeuler环境 #安装工具&#xff0c;第一次可能报错&#xff0c;可以再执行一次 make installx86 livecd-creator -d -v --config./config/euler_x86_64.ks --fslabeleuler-LiveCD --cachecache --log…

HarmonyOS—ArkTS中@Observed和@ObjectLink装饰器的嵌套类对象属性变化【鸿蒙专栏-11】

文章目录 ARKTS中@Observed和@ObjectLink装饰器的嵌套类对象属性变化@Observed 类装饰器说明装饰器参数类装饰器的使用@ObjectLink 变量装饰器说明装饰器参数同步类型允许装饰的变量类型被装饰变量的初始值举例装饰器的限制条件观察变化和行为表现观察的变化框架行为使用场景1.…

docker安装各开发环境

docker安装 安装Docker # 环境安装&#xff1a; yum -y install gcc-c# 第一步&#xff1a;安装必要的一些系统工具 yum install -y yum-utils device-mapper-persistent-data lvm2# 第二步&#xff1a;添加软件源信息 yum-config-manager --add-repo http://mirrors.aliyun.…

没有哈希时间锁定合约的跨链原子交换

在上一篇文章中&#xff0c;我们介绍了使用哈希时间锁定合约&#xff08;HTLC&#xff09;的跨链原子交换实现。 今天&#xff0c;我们介绍一种无需 HTLC 即可实现的替代方法。 这将原子交换扩展到缺乏哈希锁和时间锁的区块链。 使用 SPV 证明交易已被挖掘 让我们按照商定的价…

windows10系统更新失败无法进入系统

用户反馈早上电脑重启&#xff0c;系统在更新卡好久好进去是否更新windows11&#xff0c;选否&#xff0c;重新就反复在更新中无法进入系统。我在测试的过程也是多次更新卡好久无法进入系统&#xff0c;而且出现下面提示 windows10系统更新失败无法进入系统&#xff0c;蓝屏提…

软件工程 课后题 acmakb 总结

让你一口气复习个爽&#xff01; 具体的应用题参考 软件工程学科出现的主要原因是软件危机的出现 20世纪60年代提出了软件工程的概念 软件危机的主要原因是软件本身的特点及开发方法 软件工程的三要素是方法、工具和过程 与计算机硬件相比&#xff0c;计算机软件有哪些特点…

设备管理的方法与思路

阅读本文你将了解设备管理的思路与方法&#xff1a;一、制定全面的管理计划&#xff1b;二、标准化管理流程&#xff1b;三、设备维护与保养&#xff1b;四、风险管理与预防&#xff1b;五、引入数字化工具。 设备管理在生产制造领域是保障生产安全和效率的核心环节。通过引入…

java分布式锁分布式锁

java分布式&锁&分布式锁 锁 锁的作用&#xff1a;有限资源的情况下&#xff0c;控制同一时间段&#xff0c;只有某些线程&#xff08;用户/服务器&#xff09;能访问到资源。 锁在java中的实现&#xff1a; synchronized关键字并发包的类 缺点&#xff1a;只对单个的…