1. 动机

  • 在软件系统中,有时候面临着“一个“复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将他们组合在一起的算法却相对稳定。
  • 如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分“”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?

2. 代码示例

场景,游戏中新建房子,各种类型的房子,茅草屋、砖瓦房、别墅...

建房子几个流程是固定的:四面墙、房顶、门、窗...但是不同类型的房子,这些元素具体实现方式不同

// 场景:游戏新建房子
class House{
public:void Init(){this->BuildPart1();for (size_t i = 0; i < 4; i++){this->BuildPart2();}bool flag = this->BuildPart3();if (flag) {this->BuildPart4();}this->BuildPart5();}
protected:virtual void BuildPart1() = 0;;virtual void BuildPart2() = 0;virtual bool BuildPart3() = 0;virtual void BuildPart4() = 0;virtual void BuildPart5() = 0;
}

那可以这样做吗?将初始化动作放在子类里面,不行哈!!!因为构造函数中的调用数据静态绑定,它不会去调用子类的接口的,只会调用本类的接口,现在本类是个接口类,各个接口都是纯虚的,所以不行。

(为什么不能构造里面调用动态,简单说下,因为在子类构造之前,会先调用父类构造函数,如果调用父类构造的时候,再反过来调用子类的虚函数,这是违背基本的逻辑关系的,你得先生下来才能呀,子类都没有出生...)

// 场景:游戏新建房子
class House{
public:House(){this->BuildPart1();for (size_t i = 0; i < 4; i++){this->BuildPart2();}bool flag = this->BuildPart3();if (flag) {this->BuildPart4();}this->BuildPart5();}
protected:virtual void BuildPart1() = 0;;virtual void BuildPart2() = 0;virtual bool BuildPart3() = 0;virtual void BuildPart4() = 0;virtual void BuildPart5() = 0;
};

下面是具体实现

class StoneHouse : public House{
protected:virtual void BuildPart1(){}virtual void BuildPart2(){}virtual bool BuildPart3(){}virtual void BuildPart4(){}virtual void BuildPart5(){}
};int main(){House *p_hose = new StoneHouse();p_hose->Init();
}

3. 课程后续优化(这节讲的有点乱,不建议服用)

其实做到这一步,Builder模式基本就完毕了,但是呢,还有优化的空间,如果House接口的Init过于复杂(导致这个类很大),其实可以将这个复杂的结构再提取成一个类,重构成:

// 场景:游戏新建房子
class House{
protected:virtual void BuildPart1() = 0;;virtual void BuildPart2() = 0;virtual bool BuildPart3() = 0;virtual void BuildPart4() = 0;virtual void BuildPart5() = 0;
};// 场景:游戏新建房子
class HouseBuilder{
public:House *GetResult(){return house;}protected:House *house;virtual void BuildPart1() = 0;;virtual void BuildPart2() = 0;virtual bool BuildPart3() = 0;virtual void BuildPart4() = 0;virtual void BuildPart5() = 0;
};class StoneHouseBuilder : public HouseBuilder{
protected:virtual void BuildPart1(){}virtual void BuildPart2(){}virtual bool BuildPart3(){}virtual void BuildPart4(){}virtual void BuildPart5(){}
};class HouseDirector{HouseBuilder *house;
public:HouseDirector(HouseBuilder *house){this->house = house;}
public:House* Construct(){house->BuildPart1();for (size_t i = 0; i < 4; i++){house->BuildPart2();}bool flag = house->BuildPart3();if (flag) {house->BuildPart4();}house->BuildPart5();return house->GetResult();}
};

HourseBuilder中组合了一个house指针,并负责稳定的构建工作,其实就是将Hourse拆分成了House和HourseBuilder两个类。

4. 模式定义

将一个复杂对象的构建和其表示相分离,使得同样的构建过程(稳定)可以创建不同的表示(变化)

5. 结构

6. 要点总结

  • Builder模式主要用于“分步骤构建一个复杂对象”。在其中“步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。
  • 变化点在哪里,封装哪里--builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动。

11. 对象创建模式之 Builder模式(构建器)(不常用)相关推荐

  1. 构建器模式_我喜欢构建器模式的三个原因

    构建器模式 有三种方法可以用Java编程语言创建新对象: 伸缩构造函数(反)模式 Javabeans模式 建造者模式 与其他两种方法相比,我更喜欢使用构建器模式. 为什么? Joshua Bloch描 ...

  2. 创建型模式之Builder模式

    1.意图 将一个复杂对象的创建与它的表示分享,使得同样的构建过程可以创建不同的表示. 2.适用性 (1)当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时 (2)当构造过程必须允许被构 ...

  3. 【Builder模式】C++设计模式——构建器

    构建器 一.设计流程介绍 二.模式介绍 三.代码实现     C++设计模式大全,23种设计模式合集详解-

  4. Creational模式之Builder模式

    1.意图 将一个复杂对象的构建与它表示分离,使得相同的构建过程能够创建不同的表示. 查看很多其它请点击 2.别名 无 3.动机 一个RTF(Rich Text Format)文档交换格式的阅读器应能将 ...

  5. 建造者模式(Builder模式)详解

    在软件开发过程中有时需要创建一个复杂的对象,这个复杂对象通常由多个子部件按一定的步骤组合而成.例如,计算机是由 OPU.主板.内存.硬盘.显卡.机箱.显示器.键盘.鼠标等部件组装而成的,采购员不可能自 ...

  6. java build 模式_Java Builder 模式,你搞懂了么?

    前言:最近闲来无事的时候想着看看一些平常用的三方库源码,没想到看了之后才知道直接撸源码好伤身体,一般设计优秀的开源库都会涉及很多的设计模式,就比如 android 开发使用频繁的 okHttp 打开源 ...

  7. JAVA构造对象的几种方式(构建器、构造器)

    大家好,我是烤鸭: 今天说一下初始化对象的几种方式:   1.    多参数构造器 2.    构建器  3.    构造器后 + get/set方法 举个例子: 这里有个机构entity,提供一个默 ...

  8. 对象创建过程之二(类加载器)

    2019独角兽企业重金招聘Python工程师标准>>> JAVA为我们提供了两种动态加载机制. 第一种是隐式机制.其实new一个对象和调用类的静态方法时,就是隐式机制在工作. 第二种 ...

  9. 构建器builder模式 + lombok @Builder的介绍及使用

    参考 https://juejin.im/post/6844903862600466439 注意⚠️: 带有@Builder的类,如果加了@NoArgsConstructor,那么也必须加@AllAr ...

最新文章

  1. 官宣!全球首富马斯克:创办这所“新大学”!
  2. 默认访问首页 || 国际化||设置全局字符编码的默认设置
  3. 有关javabean的说法不正确的是_【以案说法】从业人员劳动保护用品费不能省!否则得不偿失.........
  4. python做自动化如何定位动态元素_python-web自动化-元素定位
  5. 使用 redmind 进行项目任务管理
  6. Uva 10635 Prince and Princess (LCS变形LIS)
  7. 浅谈jQuery WeUI框架
  8. 【解决报错】failed to obtain JDBC Connection
  9. 蜂巢迷宫 c语言,最强大脑的蜂巢迷宫 创意源于此
  10. 跨境运营培训品牌商店设计技巧
  11. 【文末有惊喜!】iOS日历攻略:提醒调休并过滤法定节假日
  12. 国内网络环境安装QIIME2(100%成功)
  13. 线性代数重要知识点和理论
  14. 超市购物车的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  15. 在命令行中查看apk的签名信息
  16. Android拥有系统权限,设置允许安装未知来源的应用。
  17. overview of hevc(一)
  18. 《LeetCode笔记5》:每日温度
  19. 图像对抗生成网络 GAN学习01:从头搭建最简单的GAN网络,利用神经网络生成手写体数字数据(tensorflow)
  20. 华为手机主页面显示一半_华为手机有47个状态显示图标,网友吐槽:60%类似其他国产厂商...

热门文章

  1. 涂鸦智能五重机制守护家居安全
  2. 高校宿舍管理系统管理功能范围有哪些?
  3. Kotlin中的空判断
  4. 功能测试需要注意的地方
  5. 10 legospike 官方教程 06——词语模块、更多词语模块、帮助功能
  6. 10种具有代表性的三维GIS软件系统
  7. 华为eNSP配置防火墙命令行放行
  8. Linux操作系统分析--课程总结报告
  9. SQLPLUS 格式设置
  10. java while(x )_C语言 while(!x);是什么意思?