本文实例讲述了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程序设计有所帮助。