日期: 2020-06-22 13:13:55
本文实例讲述了PHP设计模式之建造者模式(Builder)原理与用法。分享给大家供大家参考,具体如下:
这个建造者模式,我们也可以称为生成器模式,核心思想是将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式,简单点来说就是为了消除其它对象复杂的创建过程。
例如:汽车,他的发动机引擎有好多品牌,轮胎也有各种材质,内饰更是千奇百怪;鸟,他的头、翅膀以及脚有各种颜色和形状,在创建这种复杂对象的时候,我们建议使用建造者模式。
先来看一个案例来感受下什么是建造者模式:
完事代码如下:
//建造者模式,目的是消除其它对象复杂的创建过程 /* 描述一个用户的类,包含用户姓名,年龄,金钱 */ class UserInfo { protected $userName = ''; protected $userAge = ''; protected $userMoney = ''; public function setUserName($userName) { $this->userName = $userName; } public function setUserAge($userAge) { $this->userAge = $userAge; } public function setUserMoney($userMoney) { $this->userMoney = $userMoney; } public function getPeople() { echo "这个人的姓名是:" . $this->setUserName . ',年龄是:' . $this->userAge . ', 金钱:' . $this->userMoney; } } /* 实例化,并且创建这个用户的时候,是很痛苦的,需要设置用户名,年龄和金钱*/ $peopleInfo = array( 'userName' => 'initphp', 'userAge' => 28, 'userMoney' => '100元' ); $UserInfo = new UserInfo; //下面需要一步步的设置用户信息,才能得到用户详细信息,过程纠结而痛苦 $UserInfo->setUserName($peopleInfo['userName']); $UserInfo->setUserAge($peopleInfo['userAge']); $UserInfo->setUserMoney($peopleInfo['userMoney']); $UserInfo->getPeople();
//UserInfoBuilder 用户信息建造者类,将UserInfo的创建过程封装掉,开发者使用起来心情舒畅 <?php //建造者模式,目的是消除其它对象复杂的创建过程 include("UserInfo.php"); class UserInfoBuilder { protected $obj; public function __construct() { $this->obj = new UserInfo; } public function buildPeople($peopleInfo) { $this->obj->setUserName($peopleInfo['userName']); $this->obj->setUserAge($peopleInfo['userAge']); $this->obj->setUserMoney($peopleInfo['userMoney']); } public function getPeople() { $this->obj->getPeople(); } } /* 创建过程被封装了,用户使用简单了 */ $peopleInfo = array( 'userName' => 'initphp', 'userAge' => 28, 'userMoney' => '100元' ); $UserInfoBuilder = new UserInfoBuilder; $UserInfoBuilder->buildPeople($peopleInfo); //直接一个build $UserInfoBuilder->getPeople();
大概了解了之后,咱们就来继续看。
一般情况下,建造者模式一般有以下四种角色:
1.产品角色,产品角色定义自身的组成属性
2.抽象建造者,抽象建造者定义了产品的创建过程以及如何返回一个产品
3.具体建造者,具体建造者实现了抽象建造者创建产品过程的方法,给产品的具体属性进行赋值定义
4.指挥者,指挥者负责与调用客户端交互,决定创建什么样的产品
这四个角色也可以按照如下方式来理解:
再来看个实例:
<?php /** * Created by PhpStorm. * User: Jiang * Date: 2015/4/25 * Time: 9:31 */ /**具体产品角色 鸟类 * Class Bird */ class Bird { public $_head; public $_wing; public $_foot; function show() { echo "头的颜色:{$this->_head}<br/>"; echo "翅膀的颜色:{$this->_wing}<br/>"; echo "脚的颜色:{$this->_foot}<br/>"; } } /**抽象鸟的建造者(生成器) * Class BirdBuilder */ abstract class BirdBuilder { protected $_bird; function __construct() { $this->_bird=new Bird(); } abstract function BuildHead(); abstract function BuildWing(); abstract function BuildFoot(); abstract function GetBird(); } /**具体鸟的建造者(生成器) 蓝鸟 * Class BlueBird */ class BlueBird extends BirdBuilder { function BuildHead() { // TODO: Implement BuilderHead() method. $this->_bird->_head="Blue"; } function BuildWing() { // TODO: Implement BuilderWing() method. $this->_bird->_wing="Blue"; } function BuildFoot() { // TODO: Implement BuilderFoot() method. $this->_bird->_foot="Blue"; } function GetBird() { // TODO: Implement GetBird() method. return $this->_bird; } } /**玫瑰鸟 * Class RoseBird */ class RoseBird extends BirdBuilder { function BuildHead() { // TODO: Implement BuildHead() method. $this->_bird->_head="Red"; } function BuildWing() { // TODO: Implement BuildWing() method. $this->_bird->_wing="Black"; } function BuildFoot() { // TODO: Implement BuildFoot() method. $this->_bird->_foot="Green"; } function GetBird() { // TODO: Implement GetBird() method. return $this->_bird; } } /**指挥者 * Class Director */ class Director { /** * @param $_builder 建造者 * @return mixed 产品类:鸟 */ function Construct($_builder) { $_builder->BuildHead(); $_builder->BuildWing(); $_builder->BuildFoot(); return $_builder->GetBird(); } } //调用代码 header("Content-Type:text/html;charset=utf-8"); //------------------------生成器模式测试代码------------------ require_once "./Builder/Builder.php"; $director=new Director(); echo "蓝鸟的组成:<hr/>"; $blue_bird=$director->Construct(new BlueBird()); $blue_bird->Show(); echo "<br/>Rose鸟的组成:<hr/>"; $rose_bird=$director->Construct(new RoseBird()); $rose_bird->Show();
建造者模式它的优点很明显,就是它可以很好的将一个对象的实现与相关的“业务”逻辑分离开来,从而可以在不改变事件逻辑的前提下,使增加(或改变)实现变得非常容易,缺点也是同样,那就是建造者接口的修改会导致所有执行类的修改。
关于这个建造者模式,它还有以下三个扩展模式:
以下情况应当使用建造者模式:
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); ?>
咱们可以观察到,建造者模式与工厂模式是极为相似的,并且总体上,建造者模式仅仅只比工厂模式多了一个“导演类”的角色,在建造者模式中,假如把这个导演类看做是最终调用的客户端,那么图中剩余的部分就可以看作是一个简单的工厂模式了。
与工厂模式相比,建造者模式一般用来创建更为复杂的对象,因为对象的创建过程更为复杂,因此将对象的创建过程独立出来组成一个新的类——导演类。也就是说,工厂模式是将对象的全部创建过程封装在工厂类中,由工厂类向客户端提供最终的产品;而建造者模式中,建造者类一般只提供产品类中各个组件的建造,而将具体建造过程交付给导演类。由导演类负责将各个组件按照特定的规则组建为产品,然后将组建好的产品交付给客户端。
好啦,本次记录就到这里了。
更多关于PHP相关内容感兴趣的读者可查看本站专题:《php面向对象程序设计入门教程》、《PHP数组(Array)操作技巧大全》、《PHP基本语法入门教程》、《PHP运算与运算符用法总结》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》
希望本文所述对大家PHP程序设计有所帮助。