设计模式学习[11]---建造者模式

devtools/2024/11/30 9:46:19/

文章目录

  • 前言
    • 1.原理阐述
    • 2.举例
  • 总结

前言

建造者模式属于创建型模式,原型模式与工厂模式也归属于这一类。
创建型模式的特点在于,创建新对象,关于创建对象这个概念,在原型模式里面阐述过,创建对象是要深拷贝的,而不是简单的给个引用,指针之类的,这种是没有内存复制的。

下面来看看建造者模式又有什么特点?

1.原理阐述

先看官话:

建造者模式(Builder):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

说下个人理解:
先看前半句,将一个复杂对象的构建与它的表示分离。那么这里分离的意思其实就是依赖倒置的一种体现。我们在设计模式里面做分离一般都是用接口,这里前半句就提示我们在具体实现的时候要做隔离。

后半句,同样的构建过程…,什么叫同样的构建过程,就是可以认为对象的构建,流程是一致的。比如麦当劳做汉堡,多少度烤多久,制作步骤是什么,这就是流程。

再往后看,同样的构建过程可以创建不同的表示。这里放到C++里面其实就是一种多态的表现。父类的虚函数,子类继承后要重写这个虚函数。

现在做一个总结建造者模式就是,用依赖倒置的原则,将具有相同流程的对象构建过程放到一个接口类中,具体的实现由具体的子类做,来实现不同的效果。

2.举例

小时候喜欢玩游戏,尤其是小游戏。 4399 , 7 K 7 K 4399,7K7K 4399,7K7K都是我小时候沉醉的网站。

以前经常玩火柴人系列游戏,火柴人很好画,自己有时候下课发呆也会随便画画,画个火柴人嘛,一个头就是一个圈,四肢与身体,就是一根线嘛,简简单单右手就行。

任何火柴人的原型都是这么画的,都是有固定的头,躯干,四肢,那么这个在建造者模式中就可以认为是同样的构建过程,我们需要用一个接口来封装好,代码如下:

class PersonBuilder
{
public:virtual void BuildHead()=0;virtual void BuildBody()=0;virtual void BuildLeftArm()=0;virtual void BuildRightArm()=0;virtual void BuildLeftLeg()=0;virtual void BuildRightLeg()=0;
};

原理阐述中提到:将一个复杂对象的构建与它的表示分离,那么这个 P e r s o n B u i l d e r PersonBuilder PersonBuilder类只是一个构建抽象接口类,具体的表示其实还需要一个新的类。同时,不同的火柴人,脑袋大小,身体结构等都不一样,所以还需要一个具体类去实现这个抽象接口类。
代码如下:

class PersonDisplay
{
public:PersonDisplay(PersonBuilder *pb){m_pb=pb;}void CreatePerson(){m_pb->BuildHead();m_pb->BuildBody();m_pb->BuildLeftArm();m_pb->BuildRightArm();m_pb->BuildLeftLeg();m_pb->BuildRightLeg();}
private:PersonBuilder *m_pb;
};
class PersonThin:public PersonBuilder
{
public:void BuildHead(){std::cout<<"PersonThin buildHead"<<std::endl;};void BuildBody(){std::cout<<"PersonThin buildBody"<<std::endl;};void BuildLeftArm(){std::cout<<"PersonThin buildLeftArm"<<std::endl;};void BuildRightArm(){std::cout<<"PersonThin buildRightArm"<<std::endl;};void BuildLeftLeg(){std::cout<<"PersonThin buildLeftLeg"<<std::endl;};void BuildRightLeg(){std::cout<<"PersonThin buildRightLeg"<<std::endl;};
};
class PersonFat:public PersonBuilder
{
public:void BuildHead(){std::cout<<"PersonFat buildHead"<<std::endl;};void BuildBody(){std::cout<<"PersonFat buildBody"<<std::endl;};void BuildLeftArm(){std::cout<<"PersonFat buildLeftArm"<<std::endl;};void BuildRightArm(){std::cout<<"PersonFat buildRightArm"<<std::endl;};void BuildLeftLeg(){std::cout<<"PersonFat buildLeftLeg"<<std::endl;};void BuildRightLeg(){std::cout<<"PersonFat buildRightLeg"<<std::endl;};
};int main()
{PersonThin *a=new PersonThin();PersonFat *b=new PersonFat();PersonDisplay* m_pda=new PersonDisplay(a);PersonDisplay* m_pdb=new PersonDisplay(b);//也可以写成这样://PersonDisplay* m_pda=new PersonDisplay(new PersonThin());//PersonDisplay* m_pdb=new PersonDisplay(new PersonFat());m_pda->CreatePerson();m_pdb->CreatePerson();return 0;
}

本来想写伪代码的,一写就基本上都写好了。这里我们看main函数,我们用PersonDisplay这个表示类,把具体的构造过程封装了起来,但是里面的实现实际上是由具体的PersonThin类和PersonFat类去做。

总结

建造者模式适合于那种流程相对固定,且最后的需求是创建对象的场景。当然了,它本身是一个创建者模式,不创建对象的话,那就不能称之为创建者模式了。

建造者模式两个点,流程固定,依赖倒置。


http://www.ppmy.cn/devtools/138156.html

相关文章

selenium动态判断滚轮方向样例

一、说明及实现方案&#xff1a; 要根据目标元素的位置动态决定是向下滑动还是向上滑动&#xff0c;可以结合 window.pageYOffset 和目标元素的位置来实现逻辑判断。以下是实现代码&#xff1a; from selenium import webdriver from selenium.webdriver.common.by import By…

docker启动容器,语句名词解释

#启动容器代码docker run -it -d --name dev_aios -v D:\project\aialign:/www/ -v D:\project\data\dev\aios:/myfile/data/dev/aios -w /www/stand-alone-aios/aios -p 9002:9000 --ulimit core0 aialign/python-base:1.0 bash名词解释 docker run: 这是 Docker 的命令&#…

MaskRCNN训练自己的数据集

一. 数据标注 1. 安装labelme软件 conda install labelme2. 运行labelme # 命令行中直接输入 labelme3. 标注 二、训练数据处理 1. 在根目录下创建datasets/demo1文件夹&#xff0c;创建如下几个文件夹 2. 将标注好的.json文件放在json文件夹中 3. 原图放在pic文件夹中 4. …

Android 设备使用 Wireshark 工具进行网络抓包

背景 电脑和手机连接同一网络&#xff0c;想使用wireshark抓包工具抓取Android手机网络日志&#xff0c;有以下两种连接方法&#xff1a; Wi-Fi 网络抓包。USB 网络共享抓包。需要USB 数据线将手机连接到电脑&#xff0c;并在开发者模式中启用 USB 网络共享。 查看设备连接信…

【Debug】hexo-github令牌认证 Support for password authentication was removed

title: 【Debug】hexo-github令牌认证 date: 2024-07-19 14:40:54 categories: bug解决日记 description: “Support for password authentication was removed on August 13, 2021.” cover: https://pic.imgdb.cn/item/669b38ebd9c307b7e9f3e5e0.jpg 第一章 第一篇博客记录一…

新型大语言模型的预训练与后训练范式,苹果的AFM基础语言模型

前言&#xff1a;大型语言模型&#xff08;LLMs&#xff09;的发展历程可以说是非常长&#xff0c;从早期的GPT模型一路走到了今天这些复杂的、公开权重的大型语言模型。最初&#xff0c;LLM的训练过程只关注预训练&#xff0c;但后来逐步扩展到了包括预训练和后训练在内的完整…

高效处理 iOS 应用中的大规模礼物数据:以直播项目为例(1-礼物池)

引言 在现代iOS应用开发中&#xff0c;处理大规模数据是一个常见的挑战。尤其实在直播项目中&#xff0c;礼物面板作为展示用户互动的重要部分&#xff0c;通常需要实时显示海量的礼物数据。这些数据不仅涉及到不同的区域、主播的动态差异&#xff0c;还需要保证高效的加载与渲…

11、PyTorch中如何进行向量微分、矩阵微分与计算雅克比行列式

文章目录 1. Jacobian matrix2. python 代码 1. Jacobian matrix 计算 f ( x ) [ f 1 x 1 2 2 x 2 f 2 3 x 1 4 x 2 2 ] , J [ ∂ f 1 ∂ x 1 ∂ f 1 ∂ x 2 ∂ f 2 ∂ x 1 ∂ f 2 ∂ x 2 ] [ 2 x 1 2 3 8 x 2 ] \begin{equation} f(x)\begin{bmatrix} f_1x_1^22x_2\\…