我和王争学设计模式|建造者模式
目录
- 定义
- 适用场景
- 需求描述
- 代码示例
- 有趣例子
- 总结
极客时间《设计模式》(王争)
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
我和王争学设计模式|建造者模式相关推荐
- Python设计模式-建造者模式
Python设计模式-建造者模式 代码基于3.5.2,代码如下; #coding:utf-8 #建造者模式 class Burger():name = ""price = 0.0d ...
- 说说设计模式~建造者模式(Builder)
建造者模式是我的"设计模式"里创建型模式里的最后一篇,这种模式在实现中,很多架构都用到了,如MVC,MVP,MVVM,它们都是有建造者模式的精髓的,即,创建与表现分享,我们的MVC ...
- 设计模式 建造者模式_设计模式:建造者
设计模式 建造者模式 有时需要在应用程序中创建一个复杂的对象. 一种解决方案是Factory模式,另一种是Builder设计模式. 在某些情况下,您甚至可以结合使用这两种模式. 但是在本文中,我想研究 ...
- 设计建造者模式java代码,Java设计模式-建造者模式
定义 Separate the construction of a complex object from its representation so that the sameconstructio ...
- python创造者_python 设计模式-建造者模式
问题:在上一篇python设计模式:抽象工厂模式中,我们尝试用抽象工厂模式规范化了 Pizza 原材料的供应以及 Pizza 的创建.但是我们忽略了一个问题,那就是每种 Pizza 的烘焙时间依赖于生 ...
- java设计模式-建造者模式
概念:使用多个简单的对象一步一步构建成一个复杂的对象.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示. ...
- 设计模式-建造者模式(转自:http://www.cnblogs.com/cbf4life/archive/2010/01/14/1647710.html)...
11.1 变化是永恒的 又是一个周三,快要下班了,老大突然拉住我,喜滋滋地告诉我:"牛叉公司很满意我们做的模型,又签订了一个合同,把奔驰.宝马的车辆模型都交给我们公司制作了,不过这次又额外增 ...
- 大话设计模式—建造者模式
建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 一个 Builder 类会一步一步构造最 ...
- 我的Java设计模式-建造者模式
在未上大学之前,一直有个梦想"I have a dream!",就是能成为一位汽车工程师,一直幻想着开着自己设计的汽车飞奔在公路上,迷倒了万千少女.咳咳~~虽然现在没实现我的dre ...
最新文章
- 计算机右键无法新建excel2007,Win7系统安装Office2007后,Excel不能自动关联,而且右键新建菜单里也没有新建Excel的选项...
- groupByKey、reduceByKey区别(转)
- 中间件和微服务,Docker以及原生云架构的关系
- 原型链的理解_javascript之快速理解(原型链)
- Golang语言写99乘法表-双重for循环
- 如何看待阿里云加入Linux基金会金牌会员?
- 利用python自动清除Android工程中的多余资源
- PHP实现QQ达人信息抓取
- 好的技术文章应该让读者更自信而不是更自卑
- MQTT 测试工具介绍
- python脚本 游戏赚金币_Python实现王者荣耀刷金币脚本功能
- 全球与中国药用玻璃容器市场深度研究分析报告
- html5无法绘制线条,Html5画布 - 使用fabric.js绘制完美线条或不使用
- ORA-16401: archivelog rejected by RFS
- UTF8 中文占几个字节
- 小米开机the system has been destroyed
- android camera viewport rect,如何判断元素是否在可视区域ViewPort
- 进制转换(二进制,八进制,十进制,十六进制)涵盖整数与小数部分,内容的图片全为手写【详细图解】
- 有哪些好用的App云测试平台?
- 云南大学旅游文化学院计算机专业,云南大学旅游文化学院有哪些专业_什么专业好...