💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示 创建者模式中,客户端不再负责对象的创建与组装,而是把这个对象创建的责任交给其具体的创建者类,把组装的责任交给组装类,客户端支只负责对象的调用,从而明确了各个类的职责 例如,计算机是由 OPU、主板、内存、硬盘、显卡、机箱、显示器、键盘、鼠标等部件组装而成的,采购员不可能自己去组装计算机,而是将计算机的配置要求告诉计算机销售公司,计算机销售公司安排技术人员去组装计算机,然后再交给要买计算机的采购员 如游戏中的不同角色,其性别、个性、能力、脸型、体型、服装、发型等特性都有所差异 还有汽车中的方向盘、发动机、车架、轮胎等部件也多种多样;每封电子邮件的发件人、收件人、主题、内容、附件等内容也各不相同 **他们的关系是聚合关系**:------◇ 聚合是整体和个体之间的关系 **主要优点如下:** 1. 各个具体的建造者相互独立,有利于系统的扩展。 2. 客户端不必知道产品内部组成的细节,便于控制细节风险。 **其缺点如下:** 1. 产品的组成部分必须相同,这限制了其使用范围。 2. 如果产品的内部变化复杂,该模式会增加很多的建造者类,后期维护成本较大。 **以下情况应当使用建造者模式:** 1、 需要生成的产品对象有复杂的内部结构。 2、 需要生成的产品对象的属性相互依赖,建造者模式可以强迫生成顺序。 3、 在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中不易得到。 **建造者模式的效果:** 1、 建造者模式的使用使得产品的内部表象可以独立的变化。使用建造者模式可以使客户端不必知道产品内部组成的细节。 2、 每一个Builder都相对独立,而与其它的Builder(独立控制逻辑)无关。 3、 模式所建造的最终产品更易于控制。 **具体场景举例:** 在很多游戏软件中,地图包括天空、地面、背景等组成部分,人物角色包括人体、服装、装备等组成部分,可以使用建造者模式对其进行设计, 通过不同的具体建造者创建不同类型的地图或人物 >[danger] 建造者(Builder)模式和工厂模式的关注点不同:建造者模式注重零部件的组装过程,而[工厂方法模式](http://c.biancheng.net/view/1348.html)更注重零部件的创建过程,但两者可以结合使用 ![](https://img.kancloud.cn/46/4b/464b1c7f6b750f40732fbcf413c26e00_611x641.png) ~~~ class person { public $age; public $speed; public $knowledge; } //抽象建造者类 abstract class Builder{ public $_person; public abstract function setAge(); public abstract function setSpeed(); public abstract function setKnowledge(); public function __construct(Person $person){ $this->_person=$person; } public function getPerson(){ return $this->_person; } } //长者建造者 class OlderBuider extends Builder{ public function setAge(){ $this->_person->age=70; } public function setSpeed(){ $this->_person->speed="low"; } public function setKnowledge(){ $this->_person->knowledge='more'; } } //小孩建造者 class ChildBuider extends Builder{ public function setAge(){ $this->_person->age=10; } public function setSpeed(){ $this->_person->speed="fast"; } public function setKnowledge(){ $this->_person->knowledge='litte'; } } //建造指挥者 class Director{ private $_builder; public function __construct(Builder $builder){ $this->_builder = $builder; } public function built(){ $this->_builder->setAge(); $this->_builder->setSpeed(); $this->_builder->setKnowledge(); } } //实例化一个长者建造者 $oldB = new OlderBuider(new Person); //实例化一个建造指挥者 $director = new Director($oldB); //指挥建造 $director->built(); //得到长者 $older = $oldB->getPerson(); var_dump($older); ~~~ 购物车: ~~~ //购物车 (product) class ShoppingCart { # 选中的商品 private $_goods = array(); # 使用的优惠券 private $_tickets = array(); # 商品赋值 public function addGoods($goods) { $this->_goods[] = $goods; } # 优惠券赋值 public function addTicket($ticket) { $this->_tickets[] = $ticket; } public function printInfo() { # builder:goods:(衣服,鞋子), tickets:(减10) printf("goods:(%s), tickets:(%s)", implode(',', $this->_goods), implode(',', $this->_tickets)); } } //假如我们要还原购物车的东西,比如用户关闭浏览器后再打开时会根据cookie还原 $data = array( 'goods' => array('衣服', '鞋子'), 'tickets' => array('减10'), ); # 如果不使用创建者模式,则需要业务类里一步步还原购物车 /* $cart = new ShoppingCart(); foreach ($data['goods'] as $goods) { $cart->addGoods($goods); } foreach ($data['tickets'] as $ticket) { $cart->addTicket($ticket); } $cart->printInfo(); exit; */ //我们提供创建者类来封装购物车的数据组装 (比工厂模式多了一个“导演类”的角色 ) class CardBuilder { private $_card; function __construct($card) { $this->_card = $card; } function build($data) { foreach ($data['goods'] as $goods) { $this->_card->addGoods($goods); } foreach ($data['tickets'] as $ticket) { $this->_card->addTicket($ticket); } } function getCrad() { return $this->_card; } } $cart = new ShoppingCart(); $builder = new CardBuilder($cart); $builder->build($data); echo "after builder:"; $cart->printInfo(); ###### 进阶 /** * * 产品本身 */ class ShoppingCart { public $_goods; public $_tickets; } /** * 建造者抽象类 * */ abstract class Builder { public abstract function buildGoods($goods); public abstract function buildTicket($tickets); public abstract function getResult(); } /** * * 具体建造者 * 实现其具体方法 */ class CartBuilder extends Builder { private $_product; public function __construct(ShoppingCart $product) { $this->_product = new ShoppingCart(); } public function buildGoods($goods) { $this->_product->_goods=$goods; } public function buildTicket($tickets) { $this->_product->_tickets=$tickets; } public function getResult() { return $this->_product; } } /** * * 并不知道具体实现细节 只需要指挥具体建造者建造 */ class Director { private $_builder; public function __construct(Builder $builder) { $this->_builder = $builder; } public function built($data){ $this->_builder->buildGoods($data['goods']); $this->_builder->buildTicket($data['tickets']); } } $data = array( 'goods' => array('衣服', '鞋子'), 'tickets' => array('减10'), ); // client $buidler = new CartBuilder(new ShoppingCart); $director = new Director($buidler); $director->built($data); $product = $buidler->getResult(); echo "<pre>"; var_dump($product); echo "</pre>"; ~~~ ``` <?php ini_set('memory_limit','1256M'); //升级为256M内存 //(1) 产品角色:包含多个组成部件的复杂对象。 class Product { private $partA; private $partB; private $partC; public function setPartA($partA) { $this->partA=$partA; } public function setPartB($partB) { $this->partB=$partB; } public function setPartC($partC) { $this->partC=$partC; } public function show() { //显示产品的特性 echo $this->partA; echo $this->partB; echo $this->partC; } } //(2) 抽象建造者:包含创建产品各个子部件的抽象方法。 abstract class Builder { //创建产品对象 protected $product; public abstract function buildPartA(); public abstract function buildPartB(); public abstract function buildPartC(); public function __construct(){ $this->product = new Product(); } //返回产品对象 public function getResult() { return $this->product; } } //(3) 具体建造者:实现了抽象建造者接口。 class ConcreteBuilder extends Builder { public function buildPartA() { $this->product->setPartA("建造 PartA"); } public function buildPartB() { $this->product->setPartB("建造 PartB"); } public function buildPartC() { $this->product->setPartC("建造 PartC"); } } //(4) 指挥者:调用建造者中的方法完成复杂对象的创建。 class Director { private $builder; public function __construct($builder){ $this->builder=$builder; } //产品构建与组装方法 public function construct() { $this->builder->buildPartA(); $this->builder->buildPartB(); $this->builder->buildPartC(); return $this->builder->getResult(); } } class Client{ public static function main(){ $builder=new ConcreteBuilder(); $director=new Director($builder); $product=$director->construct(); $product->show(); } } Client::main(); ```