目录

  • 定义
  • 适用场景
  • 需求描述
  • 代码示例
  • 有趣例子
  • 总结

极客时间《设计模式》(王争)
Github Gitee

定义

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式也被称之为构建者模式、生成器模式

适用场景

生成器模式的主要解决的问题是批量设置初始值和检验参数,如果有这两个需求,建造者模式就有用武之地了。

如果存在下面情况中的任意一种,我们就可以使用建造者模式了:

  • 我们把类的必填属性放到构造函数中,强制创建对象的时候就设置。如果必填的属性有很多,把这些必填属性都放到构造函数中设置,那构造函数就又会出现参数列表很长的问题。如果我们把必填属性通过 set() 方法设置,那校验这些必填属性是否已经填写的逻辑就无处安放了。
  • 如果类的属性之间有一定的依赖关系或者约束条件,我们继续使用构造函数配合 set() 方法的设计思路,那这些依赖关系或约束条件的校验逻辑就无处安放了。
  • 如果我们希望创建不可变对象,也就是说,对象在创建好之后,就不能再修改内部的属性值,要实现这个功能,我们就不能在类中暴露 set() 方法。构造函数配合 set() 方法来设置属性值的方式就不适用了。

需求描述

我们需要定义一个资源池配置类 ResourcePoolConfig。这里的资源池,你可以简单理解为线程池、连接池、对象池等。在这个资源池配置类中,有以下几个成员变量,也就是可配置项。现在,请你编写代码实现这个 ResourcePoolConfig 类。

成员变量 解释 是否必填 默认值
name 资源名称 没有
maxTotal 最大总资源数量 8
maxIdle 最大空闲资源数量 8
minIdle 最小空闲资源数量 0

代码示例

我们可以把校验逻辑放置到 Builder 类中,先创建建造者,并且通过 set() 方法设置建造者的变量值,然后在使用 build() 方法真正创建对象之前做集中的校验,校验通过之后才会创建对象。并且,ResourcePoolConfig 没有提供任何 set() 方法,这样我们创建出来的对象就是不可变对象了。

<?php
namespace App;interface IBuilder
{public function build();
}
<?php
namespace App;class ResourceBuilder implements IBuilder
{const DEFAULT_MAX_TOTAL = 8;const DEFAULT_MAX_IDLE = 8;const DEFAULT_MIN_IDLE = 0;public $name;public $maxTotal;public $maxIdle;public $minIdle;public function __construct(){$this->minIdle = self::DEFAULT_MIN_IDLE;$this->maxTotal = self::DEFAULT_MAX_TOTAL;$this->maxIdle = self::DEFAULT_MAX_IDLE;}public function build(){if($this->minIdle > $this->maxTotal){throw new \Exception("...");}if($this->minIdle > $this->maxTotal ||$this->minIdle > $this->maxIdle){throw new \Exception("...");}return new ResourcePoolConfig($this);}public function setName($name){if(empty($name)) {throw new \Exception("$name can't be empty");}$this->name = $name;return $this;}public function setMaxTotal($maxTotal){if($maxTotal<0){throw new \Exception("maxTotal must above zero");}$this->maxTotal = $maxTotal;return $this;}public function setMaxIdle($maxIdle){if($maxIdle<0){throw new \Exception("maxIdle must above zero");}$this->maxIdle = $maxIdle;return $this;}public function setMinIdle($minIdle){if($minIdle<0){throw new \Exception("minIdle must above zero");}$this->minIdle = $minIdle;return $this;}
}
<?php
/*** User: 小水* Date: 2021-07-28*/namespace App;class ResourcePoolConfig
{private $name;private $maxTotal;private $maxIdle;private $minIdle;public function __construct(ResourceBuilder $builder){$this->name = $builder->name;$this->maxIdle = $builder->maxIdle;$this->maxTotal = $builder->maxTotal;$this->minIdle = $builder->minIdle;}
}
<?php
require __DIR__.'/vendor/autoload.php';$resourceBuilder = new \App\ResourceBuilder();
try{$poolConfig = $resourceBuilder->setName("resource")->setMaxIdle(10)->setMinIdle(1)->setMaxTotal(12)->build();var_dump($poolConfig);
} catch (Exception $exception){echo $exception->getMessage() . PHP_EOL;
}

输出结果

$ php client.php
object(App\ResourcePoolConfig)#2 (4) {["name":"App\ResourcePoolConfig":private]=>string(8) "resource"["maxTotal":"App\ResourcePoolConfig":private]=>int(12)["maxIdle":"App\ResourcePoolConfig":private]=>int(10)["minIdle":"App\ResourcePoolConfig":private]=>int(1)
}

有趣例子

顾客走进一家餐馆点餐,我们利用工厂模式,根据用户不同的选择,来制作不同的食物,比如有披萨、汉堡、沙拉。对于披萨来说,用户又有各种配料可以定制,比如奶酪、西红柿、起司,我们通过建造者模式根据用户选择的不同配料来制作披萨。

总结

如果构造函数参数过多,考虑使用建造者模式,先设置建造者的变量,然后再一次性地创建对象,让对象一直处于有效状态。

参考资料:
[1]. 极客时间《设计模式》(王争)
[2].《研磨设计模式》(陈臣、王斌)
[3]. 《Learning PHP设计模式》
[4]. 从零使用composer初始化PSR-4项目
[5]. https://learnku.com/docs/php-design-patterns/2018/Builder/1488
[6]. https://www.cnblogs.com/sunshine-H/p/8268553.html

我和王争学设计模式|建造者模式相关推荐

  1. Python设计模式-建造者模式

    Python设计模式-建造者模式 代码基于3.5.2,代码如下; #coding:utf-8 #建造者模式 class Burger():name = ""price = 0.0d ...

  2. 说说设计模式~建造者模式(Builder)

    建造者模式是我的"设计模式"里创建型模式里的最后一篇,这种模式在实现中,很多架构都用到了,如MVC,MVP,MVVM,它们都是有建造者模式的精髓的,即,创建与表现分享,我们的MVC ...

  3. 设计模式 建造者模式_设计模式:建造者

    设计模式 建造者模式 有时需要在应用程序中创建一个复杂的对象. 一种解决方案是Factory模式,另一种是Builder设计模式. 在某些情况下,您甚至可以结合使用这两种模式. 但是在本文中,我想研究 ...

  4. 设计建造者模式java代码,Java设计模式-建造者模式

    定义 Separate the construction of a complex object from its representation so that the sameconstructio ...

  5. python创造者_python 设计模式-建造者模式

    问题:在上一篇python设计模式:抽象工厂模式中,我们尝试用抽象工厂模式规范化了 Pizza 原材料的供应以及 Pizza 的创建.但是我们忽略了一个问题,那就是每种 Pizza 的烘焙时间依赖于生 ...

  6. java设计模式-建造者模式

    概念:使用多个简单的对象一步一步构建成一个复杂的对象.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示. ...

  7. 设计模式-建造者模式(转自:http://www.cnblogs.com/cbf4life/archive/2010/01/14/1647710.html)...

    11.1 变化是永恒的 又是一个周三,快要下班了,老大突然拉住我,喜滋滋地告诉我:"牛叉公司很满意我们做的模型,又签订了一个合同,把奔驰.宝马的车辆模型都交给我们公司制作了,不过这次又额外增 ...

  8. 大话设计模式—建造者模式

    建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 一个 Builder 类会一步一步构造最 ...

  9. 我的Java设计模式-建造者模式

    在未上大学之前,一直有个梦想"I have a dream!",就是能成为一位汽车工程师,一直幻想着开着自己设计的汽车飞奔在公路上,迷倒了万千少女.咳咳~~虽然现在没实现我的dre ...

最新文章

  1. 计算机右键无法新建excel2007,Win7系统安装Office2007后,Excel不能自动关联,而且右键新建菜单里也没有新建Excel的选项...
  2. groupByKey、reduceByKey区别(转)
  3. 中间件和微服务,Docker以及原生云架构的关系
  4. 原型链的理解_javascript之快速理解(原型链)
  5. Golang语言写99乘法表-双重for循环
  6. 如何看待阿里云加入Linux基金会金牌会员?
  7. 利用python自动清除Android工程中的多余资源
  8. PHP实现QQ达人信息抓取
  9. 好的技术文章应该让读者更自信而不是更自卑
  10. MQTT 测试工具介绍
  11. python脚本 游戏赚金币_Python实现王者荣耀刷金币脚本功能
  12. 全球与中国药用玻璃容器市场深度研究分析报告
  13. html5无法绘制线条,Html5画布 - 使用fabric.js绘制完美线条或不使用
  14. ORA-16401: archivelog rejected by RFS
  15. UTF8 中文占几个字节
  16. 小米开机the system has been destroyed
  17. android camera viewport rect,如何判断元素是否在可视区域ViewPort
  18. 进制转换(二进制,八进制,十进制,十六进制)涵盖整数与小数部分,内容的图片全为手写【详细图解】
  19. 有哪些好用的App云测试平台?
  20. 云南大学旅游文化学院计算机专业,云南大学旅游文化学院有哪些专业_什么专业好...

热门文章

  1. 【GlobalMapper精品教程】012:WGS84转2000地理坐标系与平面坐标系
  2. 一次HTTP链接会产生多少数据流量
  3. spring技巧之bean加载顺序控制
  4. 计算机考研854题型,2020哈尔滨工业大学计算机考研854真题回忆版
  5. Unity中计算面法线与顶点法线
  6. Java线程池实现多消费者批量处理队列消息
  7. 计算机核心期刊(北大核心)投稿意见
  8. python six模块升级方法
  9. 【Unity】Inspector属性
  10. 【100%通过率】华为OD机试真题 Java 实现【完美走位】【2022.11 Q4新题】