1. 概述
开发过程中,当遇到一个“复杂的对象”在创建工作,该对象由一定各个部分的子对象用一定的算法构成,由于需求的变化,复杂对象的各个部分经常面临剧烈的变化,但将它们组合在一起的算法相对稳定。如何提供一种“封装机制”来隔离复杂对象的各个部分的变化,从而保持系统中的稳定构造算法而不随需求的变化而变化。即:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不两只的表示。
2. 示例
一个套餐销售的例子。
指导者:收银员
<?php /** * 指导者:收银员 * */ class DirectorCashier { /** * 收银餐馆员工返回的食物 * */ public function buildFood(Builder $builder) { $builder->buildPart1(); $builder->buildPart2(); } }
抽象建造者
/** * 抽象建造者 * */ abstract class Builder { /** * 创建产品的第一部分 */ public abstract function buildPart1(); /** * * 创建产品的第二部分 */ public abstract function buildPart2(); /** * * 返回产品 */ public abstract function getProduct(); }
具体建造者类
/** * 具体建造者类:餐馆员工,返回的套餐是:汉堡两个+饮料一个 * */ class ConcreteBuilder1 extends Builder { protected $_product = null;//产品对象 function __construct(){ $this->_product = new Product(); } /** * 创建产品的第一部分::汉堡=2 */ public function buildPart1() { $this->_product->add('Hamburger',2); } /** * * 创建产品的第二部分: */ public function buildPart2() { $this->_product->add('Drink', 1); } /** * 返回产品对象 : * */ public function getProduct() { return $this->_product; } } /** * 具体建造者类:餐馆员工,汉堡1个+饮料2个 * */ class ConcreteBuilder2 extends Builder { protected $_product = null;//产品对象 function __construct(){ $this->_product = new Product(); } /** * 创建产品的第一部分:汉堡 */ public function buildPart1() { $this->_product->add('Hamburger', 1); } /** * * 创建产品的第二部分:drink=2 */ public function buildPart2() { $this->_product->add('Drink', 2); } /** * 返回产品对象 : * */ public function getProduct() { return $this->_product; } }
产品类
/** * 产品类 */ class Product { public $products = array(); /** * 添加具体产品 */ public function add($name, $value) { $this->products[$name] = $value; } /** * 给顾客查看产品 */ public function showToClient() { foreach ($this->products as $key => $v) { echo $key , '=' , $v ,'<br>'; } } }
客户端程序
<pre name="code" class="php"> //客户程序 class Client { /** * 顾客购买套餐 * */ public function buy($type) { //指导者,收银员 $director = new DirectorCashier(); //餐馆员工,收银员 $class = new ReflectionClass('ConcreteBuilder' .$type ); $concreteBuilder = $class->newInstanceArgs(); //收银员组合员工返回的食物 $director->buildFood($concreteBuilder); //返回给顾客 $concreteBuilder->getProduct()->showToClient(); } } //测试 ini_set('display_errors', 'On'); $c = new Client(); $c->buy(1);//购买套餐1 $c->buy(2);//购买套餐1</pre> <pre></pre> <pre></pre> <pre></pre>
3. 建造者模式与工厂模式的区别
与工厂模式相比,建造者模式一般用来创建更为复杂的对象,因为对象的创建过程更为复杂,因此将对象的创建过程独立出来组成一个新类-导演类。也就是说,工厂模式是将对象的全部创建过程封装在工厂类中,由工厂类向客户端提供最终的产品;而建造者模式中,建造者类一般只提供产品类中各个组件的建造,而将具体建造过程交付给导演类,由导演类负责将各个组件按照特定的规则组建为产品,然后将组建好的产品交付给客户端。