PHP设计模式之建造者模式(Builder)原理与用法案(3)

建造者模式它的优点很明显,就是它可以很好的将一个对象的实现与相关的“业务”逻辑分离开来,从而可以在不改变事件逻辑的前提下,使增加(或改变)实现变得非常容易,缺点也是同样,那就是建造者接口的修改会导致所有执行类的修改。

关于这个建造者模式,它还有以下三个扩展模式:

  1. 抽象工厂模式(abstract factory模式):在抽象工厂模式中,每一次工厂对象被调用时都会返还一个完整的产品对象,而客户端可能会将这些产品组装成一个更大更复杂的产品,也可能不会。建造者模式则不同,它一点一点地建造出一个复杂的产品,而这个产品的组装过程发生在建造者内部。二者的区别在于是否有组装过程,组装过程发生的位置。这两个设计模式可以连起来用,客户端通过调用一个建造角色,间接调用另一个抽象工厂模式的工厂角色。工厂模式返还不同产品族的零件,而建造者模式则把它们组装起来。
  2. 策略模式(strategy模式):建造者模式在结构上很接近于策略模式,事实上建造者模式是策略模式的一种特殊情况。二者的区别在于用意不同。建造者模式作用于客户端一点一点的建造新的对象,而策略模式的目的是为算法提供抽象的接口。
  3. 建造者模式与模板方法模式:建造者模式在退化、失去导演者角色后,可以发展到模板方法模式(即将建造过程的算法实现放在建造角色中)。

以下情况应当使用建造者模式:

   1、 需要生成的产品对象有复杂的内部结构。
   2、 需要生成的产品对象的属性相互依赖,建造者模式可以强迫生成顺序。
   3、 在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中不易得到。

使用建造者模式主要有以下效果:

   1、 建造者模式的使用使得产品的内部表象可以独立的变化。使用建造者模式可以使客户端不必知道产品内部组成的细节。
   2、 每一个Builder都相对独立,而与其它的Builder无关。
   3、 模式所建造的最终产品更易于控制。

咱们接下来,来尝试设计一个车的组装过程,这个是网上经典的案例,如下:

<?php
/** 
 * 建造者模式
 */ 
//需要建造的产品(product)
class Car
{/*{{{*/
  public $name;
  public $engine;//发动机
  public $chassis;//底盘
  public $body;//车身
  public $equipment;//电器设备
  public function setName($name)
  {
    $this->name = $name;
  }
  public function setEngine($engine)
  {
    $this->engine = $engine;
  }
  public function setChassis($chassis)
  {
    $this->chassis = $chassis;
  }
  public function setBody($body)
  {
    $this->body = $body;
  }
  public function setEquipment($equipment)
  {
    $this->equipment = $equipment;
  }
  public function show()
  {
    echo "名称:".$this->name."\r\n";
    echo "引擎:".$this->engine."\r\n";
    echo "底盘:".$this->chassis."\r\n";
    echo "车身:".$this->body."\r\n";
    echo "电子设备:".$this->equipment."\r\n";
  }
}/*}}}*/
//builder
interface IBuilder
{/*{{{*/
  public function builderName();
  public function builderEngine();
  public function builderChassis();
  public function builderBody();
  public function builderEquipment();
  public function getCar();
}/*}}}*/
//红旗车builder
class RedBuilder implements IBuilder
{/*{{{*/
  public $car;
  public function __construct()
  {
    $this->car = new Car();
  }
  public function builderName()
  {
    $this->car->setName('红旗'); 
  }
  public function builderEngine()
  {
    $this->car->setEngine('国产发动机'); 
  }
  public function builderChassis()
  {
    $this->car->setChassis('超大底盘'); 
  }
  public function builderBody()
  {
    $this->car->setBody('超大'); 
  }
  public function builderEquipment()
  {
    $this->car->setEquipment('电子设备'); 
  }
  public function getCar()
  {
    return $this->car;
  }
}/*}}}*/
//QQ车builder
class QQBuilder implements IBuilder
{/*{{{*/
  public $car;
  public function __construct()
  {
    $this->car = new Car();
  }
  public function builderName()
  {
    $this->car->setName('QQ'); 
  }
  public function builderEngine()
  {
    $this->car->setEngine('国产发动机'); 
  }
  public function builderChassis()
  {
    $this->car->setChassis('小底盘'); 
  }
  public function builderBody()
  {
    $this->car->setBody('小'); 
  }
  public function builderEquipment()
  {
    $this->car->setEquipment('电子设备'); 
  }
  public function getCar()
  {
    return $this->car;
  }
}/*}}}*/
//组装者(director)
class CarDirector
{/*{{{*/
  public function make(IBuilder $builder)
  {
    $builder->builderName();
    $builder->builderEngine();
    $builder->builderChassis();
    $builder->builderBody();
    $builder->builderEquipment();
    return $builder->getCar();
  }
}/*}}}*/
class Client
{/*{{{*/
  public static function main($argv)
  {
    $director = new CarDirector(); 
    $redBuilder = new RedBuilder();
    $car = $director->make($redBuilder);
    $car->show();
    echo "\r\n";
    $qqBuilder = new QQBuilder();
    $car = $director->make($qqBuilder);
    $car->show();
  }
}/*}}}*/
Client::main($argv);
?>


      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/1838.html