简介
建造者模式可将对象的初始化转变成一步步配置的过程。如当对象的初始化时有很多可选参数,建造者模式能够定制参数实现对象的创立。益处有:
- 定制对象参数
- 针对不同参数,做不同的校验,如当设置了三角形的两个边长,设置第三个边时必须满足两边之和大于第三边的条件。
角色
Builder 类
定义建造一个Product分几个步骤
具体 Builder 类
实现不同的步骤
Director
属于疾速建造某一种产品的办法,如 Director 提供了创立自动挡和手动挡汽车两种办法,创立自动挡汽车中其实是调用 setA setB,而创立主动单汽车中调用setC setD。也能够不应用 Director,间接应用 Builder 的 setA setB 去设置属性
要被实例化的类
初始化时可定制的参数较多,如 setA setB setC...
类图
图中的 Director 在 make 办法中封装了设置产品属性的步骤,通过传入不同的 builder 类,实现不同的实现步骤,创立不同的产品。
代码
interface Builder{ public function producePartA(): void; public function producePartB(): void; public function producePartC(): void;}class ConcreteBuilder1 implements Builder{ private $product; public function __construct() { $this->reset(); } public function reset(): void { $this->product = new Product1(); } public function producePartA(): void { $this->product->parts[] = "PartA1"; } public function producePartB(): void { $this->product->parts[] = "PartB1"; } public function producePartC(): void { $this->product->parts[] = "PartC1"; } public function getProduct(): Product1 { $result = $this->product; $this->reset(); return $result; }}/** * EN: It makes sense to use the Builder pattern only when your products are * quite complex and require extensive configuration. * * Unlike in other creational patterns, different concrete builders can produce * unrelated products. In other words, results of various builders may not * always follow the same interface. * * RU: , * . * * , * . , * . */class Product1{ public $parts = []; public function listParts(): void { echo "Product parts: " . implode(', ', $this->parts) . "\n\n"; }}class Director{ private $builder; public function setBuilder(Builder $builder): void { $this->builder = $builder; } public function buildMinimalViableProduct(): void { $this->builder->producePartA(); } public function buildFullFeaturedProduct(): void { $this->builder->producePartA(); $this->builder->producePartB(); $this->builder->producePartC(); }}function clientCode(Director $director){ $builder = new ConcreteBuilder1(); $director->setBuilder($builder); echo "Standard basic product:\n"; $director->buildMinimalViableProduct(); $builder->getProduct()->listParts(); echo "Standard full featured product:\n"; $director->buildFullFeaturedProduct(); $builder->getProduct()->listParts(); // 不应用 Director,间接操作 builder 来创立产品 echo "Custom product:\n"; $builder->producePartA(); $builder->producePartC(); $builder->getProduct()->listParts();}$director = new Director();clientCode($director);
output:
Standard basic product:Product parts: PartA1Standard full featured product:Product parts: PartA1, PartB1, PartC1Custom product:Product parts: PartA1, PartC1