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

设计模式 创建者模式

设计模式 创建者模式

  • 前言
  • 原来代码
  • 使用设计模式
  • 总结
  • 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;
}

相关文章:

设计模式 创建者模式

设计模式 创建者模式 前言原来代码使用设计模式总结Builder模式在源码中的应用&#xff1a;其他代码 前言 “对象创建”模式——绕开new 工厂模式 抽象工厂 原型模式 构建器 动机与背景 目前需要建造一个房子&#xff0c;建造房子需要一系列特定的步骤&#xff0c;但是房子的类…...

排序算法--插入排序

实现逻辑 ① 从第一个元素开始&#xff0c;该元素可以认为已经被排序 ② 取出下一个元素&#xff0c;在已经排序的元素序列中从后向前扫描 ③如果该元素&#xff08;已排序&#xff09;大于新元素&#xff0c;将该元素移到下一位置 ④ 重复步骤③&#xff0c;直到找到已排序的元…...

【操作宝典】SQL巨擘:掌握SQL Server Management的终极秘籍!

目录 ⛳️【SQL Server Management】 ⛳️1. 启动登录 ⛳️2. 忘记密码 ⛳️3. 操作数据库和表 3.1 新建数据库text 3.2 新建表 3.3 编辑表 3.4 编写脚本 ⛳️【SQL Server Management】 ⛳️1. 启动登录 需要开启服务 ⛳️2. 忘记密码 登录windows--> 安全性 -->…...

Airtest遇到模拟器无法输入中文的情况该如何处理?

1. 前言 最近有收到同学们的一些提问&#xff0c;使用Airtest的 text 接口&#xff0c;发现在部分模拟器上&#xff0c; text 无法输入中文&#xff0c;不知道该怎么处理。 今天我们就输入这个小问题&#xff0c;来详细聊一下。 2. Airtest的输入法简介 对于Android设备来说…...

从农夫山泉家族任命,看“食企二代”的接班与传承

本文转载自产业科技 农夫山泉再次引发舆论关注&#xff0c;起因是一则人事任命消息。 市场消息称&#xff0c;农夫山泉对区域及人员进行了调整&#xff0c;其总部所在地浙江省被划分为四个区域&#xff0c;在以往浙南、浙北基础上多了浙西大区以及杭州大区&#xff0c;其中农…...

JavaScript启动本地应用程序

JavaScript调起本地应用程序 以下内容&#xff0c;自定义部分我也还未经过实际验证&#xff0c;酌情查看。 文章目录 JavaScript调起本地应用程序确定协议调用协议传参自定义写入协议获取参数 在浏览器中通过 JavaScript调起本地应用程序的一个可行方法就是 通过协议调起。 …...

软件工程理论与实践 (吕云翔)第十四章 软件维护与软件工程管理课后习题与解析

第十四章 软件维护与软件工程管理 1.判断题 &#xff08;1&#xff09;代码行技术是比较简单的定量估算软件规模的方法。(√) &#xff08;2&#xff09;功能点技术依据对软件信息域特性和软件复杂性的评估结果&#xff0c;估算软件规模。&#xff08;√&#xff09; &#…...

Flutter 桌面应用开发之读写Windows注册表

文章目录 需求来源Windows查询Windows版本号方法1. 如何查看Windows版本号2. Windows开发如何通过代码查询Windows版本号(1) 使用C#代码&#xff1a;(2) 使用VB.NET代码 3.通过注册表查看Windows版本信息 Flutter查询Windows版本号方法依赖库支持平台实现步骤1. 在pubspec.yaml…...

【Java Spring】SpringBoot 日志系统

文章目录 一、Spring Boot 日志系统1.1 Spring Boot 日志框架1.2 自定义日志打印1.3 日志级别设置1.4 日志持久化1.5 lombok 简化日志输出 一、Spring Boot 日志系统 1.1 Spring Boot 日志框架 SLF4J 和 logback都是spring boot内置的日志框架&#xff0c;开发者只负责调用对…...

Rust UI开发(四):iced中如何添加菜单栏(串口调试助手)

注&#xff1a;此文适合于对rust有一些了解的朋友 iced是一个跨平台的GUI库&#xff0c;用于为rust语言程序构建UI界面。 这是一个系列博文&#xff0c;本文是第四篇&#xff0c;前三篇链接&#xff1a; 1、Rust UI开发&#xff08;一&#xff09;&#xff1a;使用iced构建UI时…...

P19 C++ 构造函数的成员初始化列表

目录 前言 01 如果不用成员列表如何初始化变量 02 成员列表初始化 03 为什么要使用成员列表初始化呢&#xff1f; 04 案例代码 前言 本期我们聊聊构造函数初始化列表。 你应该经常使用成员初始化列表&#xff0c;如果你不喜欢这种代码风格&#xff0c;建议你还是慢慢习惯吧…...

acwing算法基础之数学知识--Nim游戏和集合Nim游戏

目录 1 基础知识2 模板3 工程化 1 基础知识 &#xff08;一&#xff09; Nim游戏&#xff1a; n n n堆物品&#xff0c;每堆有 a i a_i ai​个&#xff0c;两个玩家轮流取走任意一堆的任意个物品&#xff0c;但不能不取。取走最后一个物品的人获胜。 结论&#xff1a;如果这n…...

大数据Doris(二十八):Routine Load查看和修改作业

文章目录 Routine Load查看和修改作业 一、查看导入作业状态...

顺序表总结

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 目录 &#x1f324;️arraylist的简…...

flutter 文本不随系统设置而改变大小[最全的整理]

文本不随系统设置而改变大小[四] 前言方案十九&#xff1a;使用LayoutBuilder和RichText方案二十&#xff1a;使用Transform.scale方案二十一&#xff1a;使用自定义文本缩放因子方案二十二&#xff1a;使用SingleChildScrollView方案二十三&#xff1a;使用FittedBox方案二十四…...

python -opencv 图像锐化

python -opencv 图像锐化 图像锐化其实&#xff0c;是一种增强图片对比度的技术&#xff0c;我们可以通过计算图像的导数&#xff0c;把导数绝对值数值大于零的数值加回原图像&#xff0c;通过这种方法&#xff0c;可以增强图像的对比度。 实现代码如下&#xff1a; import c…...

数字电源为什么一般用DSP控制,而不能用普通的单片机?

数字电源为什么一般用DSP控制&#xff0c;而不能用普通的单片机&#xff1f; 首先你要清楚&#xff0c;数字电源需要一个芯片具备什么功能&#xff1f; 1 能发PWM波 &#xff0c;并且具备保护关断功能&#xff1b; 电源对PWM发波 要求很高&#xff0c;精度要ns级甚至ps级的&…...

个人投资白银收益怎么样?

个人投资白银是可以带来丰厚的收益&#xff0c;但收益的具体情况取决于多种因素。以下是一些明确的答案和举例&#xff0c;帮助投资者更好地理解个人投资白银的收益情况。 白银市场的价格波动是决定投资收益的主要因素之一&#xff0c;白银价格受全球经济形势、地缘局势风险、…...

代码随想录算法训练营 ---第四十五天

前言&#xff1a; 昨天的题做过之后&#xff0c;今天的题基本上都很简单&#xff0c;但是要注重一下细节。 第一题&#xff1a; 简介&#xff1a; 动态规划五部曲&#xff1a; 1.确定dp数组的含义 dp[i]&#xff1a;爬到有i个台阶的楼顶&#xff0c;有dp[i]种方法 2.确定dp…...

【密码学】【多方安全计算】不经意传输(Oblivious Transfer,OT)

文章目录 不经意传输&#xff08;oblivious transfer&#xff09;定义不经意传输的实例&#xff08;1 out 2&#xff0c;二选一不经意传输&#xff09;基于RSA的1 out 2 不经意传输疑问 不经意传输&#xff08;oblivious transfer&#xff09;定义 不经意传输&#xff08;obli…...

VCS覆盖率进阶:用功能覆盖率精准验证复杂SoC设计,提升验证效率

VCS覆盖率进阶&#xff1a;用功能覆盖率精准验证复杂SoC设计&#xff0c;提升验证效率 在当今SoC设计复杂度呈指数级增长的背景下&#xff0c;传统的代码覆盖率已难以满足验证完备性需求。当RTL代码量突破千万行量级时&#xff0c;仅靠行覆盖率和分支覆盖率就像用渔网捕鱼——看…...

病理切片AI分析实战:手把手教你用CLAM处理WSI数据(附避坑指南)

病理切片AI分析实战&#xff1a;CLAM框架下的WSI智能诊断全流程解析 当一张病理切片在显微镜下被数字化为超过10万像素的全切片图像&#xff08;WSI&#xff09;时&#xff0c;传统的人工分析方式正面临前所未有的效率瓶颈。我们曾见证某三甲医院病理科主任在连续工作8小时后&a…...

保姆级教程:手把手教你为RTA-OS硬件Counter写那4个要命的回调函数(含避坑指南)

嵌入式工程师实战指南&#xff1a;RTA-OS硬件计数器回调函数开发全解析 在汽车电子控制单元&#xff08;ECU&#xff09;开发中&#xff0c;实时操作系统&#xff08;RTOS&#xff09;的精确时间管理能力直接关系到系统可靠性。作为符合AUTOSAR标准的实时操作系统&#xff0c;R…...

【java工程师快速上手go】二.Go进阶特性

目录 写在前面 一、面向对象编程 1.1 结构体&#xff1a;Go的"类" 1.2 匿名字段与嵌入 1.3 结构体的组合优势 1.4 接口&#xff1a;鸭子类型的魅力 1.5 空接口与类型断言 1.6 接口组合 1.7 封装&#xff1a;大小写可见性 二、并发编程核心 2.1 Goroutine&…...

IoT-Technical-Guide:物联网平台API限流与防护策略终极指南

IoT-Technical-Guide&#xff1a;物联网平台API限流与防护策略终极指南 【免费下载链接】IoT-Technical-Guide :honeybee: IoT Technical Guide --- 从零搭建高性能物联网平台及物联网解决方案和Thingsboard源码分析 :sparkles: :sparkles: :sparkles: (IoT Platform, SaaS, MQ…...

千问3.5写小说app2025推荐,助力高效创作体验

千问3.5写小说app2025推荐&#xff0c;助力高效创作体验在当今数字化时代&#xff0c;写小说的方式发生了巨大的变革&#xff0c;越来越多的创作者借助写小说APP来提升创作效率和质量。据《2025中国网络文学创作工具发展报告》显示&#xff0c;2025年使用写小说APP进行创作的作…...

如何快速移除Windows Defender:面向开发者的完整解决方案深度指南

如何快速移除Windows Defender&#xff1a;面向开发者的完整解决方案深度指南 【免费下载链接】windows-defender-remover A tool which is uses to remove Windows Defender in Windows 8.x, Windows 10 (every version) and Windows 11. 项目地址: https://gitcode.com/gh_…...

PCB设计实战:机械孔选型、布局与可靠性设计全解析

1. 机械孔的基础认知与分类详解 机械孔在PCB设计中就像建筑物的承重柱&#xff0c;既要承担物理支撑又要兼顾功能传导。我第一次设计带大功率器件的PCB时&#xff0c;就因为机械孔选型不当导致散热不良&#xff0c;整个项目返工。现在回头看&#xff0c;机械孔的选择其实有章可…...

一文读懂深度学习的完整学习路径是什么

一文读懂深度学习的完整学习路径是什么 标签&#xff1a;#深度学习、#人工智能、#自然语言处理、#神经网络、#机器学习、#计算机视觉、#python ### 第一部分&#xff1a;为什么很多人学深度学习却找不到工作&#xff1f;### 第二部分&#xff1a;企业真正需要的技能是什么&…...

《王者荣耀世界》公测开服!开荒攻略+手机摸鱼,超全攻略一篇搞定!

腾讯天美工作室的《王者荣耀世界》PC端今天&#xff08;4月10日&#xff09;7:00已经正式开服了&#xff01;作为王者IP首个开放世界RPG&#xff0c;这波是真的能“走进”王者大陆了&#xff01;这里整理了开服情报新手开荒攻略摸鱼黑科技&#xff0c;新老玩家都能用上&#xf…...