设计模式 创建者模式

2023-12-02 17:30

本文主要是介绍设计模式 创建者模式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

设计模式 创建者模式

  • 前言
  • 原来代码
  • 使用设计模式
  • 总结
  • 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.chinasem.cn/article/446193

相关文章

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

模版方法模式template method

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/template-method 超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。 上层接口有默认实现的方法和子类需要自己实现的方法

【iOS】MVC模式

MVC模式 MVC模式MVC模式demo MVC模式 MVC模式全称为model(模型)view(视图)controller(控制器),他分为三个不同的层分别负责不同的职责。 View:该层用于存放视图,该层中我们可以对页面及控件进行布局。Model:模型一般都拥有很好的可复用性,在该层中,我们可以统一管理一些数据。Controlller:该层充当一个CPU的功能,即该应用程序

迭代器模式iterator

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/iterator 不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素

《x86汇编语言:从实模式到保护模式》视频来了

《x86汇编语言:从实模式到保护模式》视频来了 很多朋友留言,说我的专栏《x86汇编语言:从实模式到保护模式》写得很详细,还有的朋友希望我能写得更细,最好是覆盖全书的所有章节。 毕竟我不是作者,只有作者的解读才是最权威的。 当初我学习这本书的时候,只能靠自己摸索,网上搜不到什么好资源。 如果你正在学这本书或者汇编语言,那你有福气了。 本书作者李忠老师,以此书为蓝本,录制了全套视频。 试

利用命令模式构建高效的手游后端架构

在现代手游开发中,后端架构的设计对于支持高并发、快速迭代和复杂游戏逻辑至关重要。命令模式作为一种行为设计模式,可以有效地解耦请求的发起者与接收者,提升系统的可维护性和扩展性。本文将深入探讨如何利用命令模式构建一个强大且灵活的手游后端架构。 1. 命令模式的概念与优势 命令模式通过将请求封装为对象,使得请求的发起者和接收者之间的耦合度降低。这种模式的主要优势包括: 解耦请求发起者与处理者

springboot实战学习(1)(开发模式与环境)

目录 一、实战学习的引言 (1)前后端的大致学习模块 (2)后端 (3)前端 二、开发模式 一、实战学习的引言 (1)前后端的大致学习模块 (2)后端 Validation:做参数校验Mybatis:做数据库的操作Redis:做缓存Junit:单元测试项目部署:springboot项目部署相关的知识 (3)前端 Vite:Vue项目的脚手架Router:路由Pina:状态管理Eleme

状态模式state

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/state 在一个对象的内部状态变化时改变其行为, 使其看上去就像改变了自身所属的类一样。 在状态模式中,player.getState()获取的是player的当前状态,通常是一个实现了状态接口的对象。 onPlay()是状态模式中定义的一个方法,不同状态下(例如“正在播放”、“暂停

软件架构模式:5 分钟阅读

原文: https://orkhanscience.medium.com/software-architecture-patterns-5-mins-read-e9e3c8eb47d2 软件架构模式:5 分钟阅读 当有人潜入软件工程世界时,有一天他需要学习软件架构模式的基础知识。当我刚接触编码时,我不知道从哪里获得简要介绍现有架构模式的资源,这样它就不会太详细和混乱,而是非常抽象和易

使用Spring Boot集成Spring Data JPA和单例模式构建库存管理系统

引言 在企业级应用开发中,数据库操作是非常重要的一环。Spring Data JPA提供了一种简化的方式来进行数据库交互,它使得开发者无需编写复杂的JPA代码就可以完成常见的CRUD操作。此外,设计模式如单例模式可以帮助我们更好地管理和控制对象的创建过程,从而提高系统的性能和可维护性。本文将展示如何结合Spring Boot、Spring Data JPA以及单例模式来构建一个基本的库存管理系统