关闭顶部展开顶部

《PHP设计模式介绍》第三章 工厂模式(6)_PHP教程

编辑Tag赚U币
教程Tag:暂无Tag,欢迎添加,赚取U币!

推荐:《PHP设计模式介绍》第二章 值对象模式
在所有的最简单的程序中,大多数对象都有一个标识,一个重要的商业应用对象,例如一个Customer或者一个SKU,有一个或者更多的属性---id,name,email地址,这样可以把它从同一个类的其他实例区分开

“工厂”促进多态

控制被送回对象的内在状态固然重要, 但是如果促进多态即返回相同的接口多种类的对象,可以使得工厂模式的功能更为强大。

让我们再次看一下Monopoly的例子,然后执行购买游戏中的道具的行为。在游戏中,你的任务就是买道具,包括一些基本动作。更进一步说, 有三种不同的道具: Street,RailRoad和Utility。所有三个类型的道具有一些共同点: 每个道具都被一个玩家拥有; 每个都有价格;而且每个都能为它的拥有者产生租金只要其他的玩家在它上面登陆。但道具之间还是存在差异的,举例来说, 计算租金的多少就取决于道具的类型。

下列的代码展示了一个Property的基本类:

// PHP5
abstract class Property {
protected $name;
protected $price;
protected $game;
function __construct($game, $name, $price) {
$this->game = $game;
$this->name = $name;
$this->price = new Dollar($price);
}
abstract protected function calcRent();
public function purchase($player) {
$player->pay($this->price);
$this->owner = $player;
}
public function rent($player) {
if ($this->owner
&& $this->owner != $player
$player($this->calcRent())
);
}
}
}

这里, Property类和CalcRent() 方法都被声明为基类。

注:术语 – 基类
一个基类就是不能被直接实例化的类。 一个基础的类包含一个或更多的基础方法,这些方法必须在子类被覆盖。一旦所有的抽象方法被覆盖了, 子类也就产生了。
基类为许多相似的类创造了好的原型。
CalcRent() 方法必须在子类被覆盖,从而形成一个具体的类。因此, 每个子类包括:Street,RailRoad和Utility,和必须定义的calcRent() 方法。

为实现以上的情况,这三个类可以定义为:

class Street extends Property {
protected $base_rent;
public $color;
public function setRent($rent) {
$this->base_rent = new Dollar($rent);
}
protected function calcRent() {
if ($this->game->hasMonopoly($this->owner, $this->color)) {
return $this->base_rent->add($this->base_rent);
}
return $this->base_rent;
}
}
class RailRoad extends Property {
protected function calcRent() {
switch($this->game->railRoadCount($this->owner)) {
case 1: return new Dollar(25);
case 2: return new Dollar(50);
case 3: return new Dollar(100);
case 4: return new Dollar(200);
default: return new Dollar;
}
}
}
class Utility extends Property {
protected function calcRent() {
switch ($this->game->utilityCount($this->owner)) {
case 1: return new Dollar(4*$this->game->lastRoll());
case 2: return new Dollar(10*$this->game->lastRoll());
default: return new Dollar;
}
}
}

每个子类都继承了Property类,而且包括它自己的protected ClacRent() 方法。随着所有的基础方法都被定义, 每个子类都被实例化了。

为了开始游戏, 所有的Monopoly道具必须被创建起来。因为这章是介绍工厂模式的,所有Property的类型存在很多共性,你应该想到多态性,从而建立所有需要的对象。

我们还是以道具工厂类开始。 在我住的地方,政府的Assessor(定税人)掌握了税务和契约, 因此我命名它为的道具定税工厂。下一步,这个工厂将制造全部的专有道具。在真正应用时,所有的Monopoly道具的数值可能都取自于一个数据库或者一个文本, 但是对于这一个例子来说, 可以仅仅用一个数组来代替:

class Assessor {
protected $prop_info = array(
// streets
‘Mediterranean Ave.’ => array(‘Street’, 60, ‘Purple’, 2)
,’Baltic Ave.’ => array(‘Street’, 60, ‘Purple’, 2)
//more of the streets...
,’Boardwalk’ => array(‘Street’, 400, ‘Blue’, 50)
// railroads
,’Short Line R.R.’ => array(‘RailRoad’, 200)
//the rest of the railroads...
// utilities
,’Electric Company’ => array(‘Utility’, 150)
,’Water Works’ => array(‘Utility’, 150)
);
}

Property子类需要实例化Monopoly道具。现在,我们只是简单的用一个函数定义实例化变量$game,那么再把它加入Assessor类好了。

class Assessor {
protected $game;
public function setGame($game) { $this->game = $game; }
protected $prop_info = array(/* ... */);
}

也许你会偏向于选择使用数据库记录数据,不会用数组, 因为有一大堆的参数不可避免地要被罗列。如果是这样的话,可以考虑使用" 引入叁数对象 " 进行重构。

注:重构-引入叁数对象
方法中如果有很多参数,常常变得很复杂,而且容易导致错误。你可以引入一个封装参数的对象来替代一大堆的参数。举例来说,“start date” and “end date” 叁数可以用一个 DateRange 对象一起代替。

在Monopoly这个例子中,这个参数对象应该是什么呢?PropertyInfo,怎样?它的目的是使每个道具参数数组引入 PropertyInfo 类的构造器中,然后返回一个新对象。目的就意味着设计, 依照 TDD, 那意味着一个测试情形。

分享:《PHP设计模式介绍》第一章 编程惯用法
学习一门新的语言意味着要采用新的惯用法。这章将介绍或者可能重新强调一些惯用法。你会发现这些惯用法在你要在代码中实现设计模式时候是非常有用的。 在这里总结的许多编程惯用法都是很值得

来源:模板无忧//所属分类:PHP教程/更新时间:2008-08-22
loading.. 评论加载中....
相关PHP教程
闂佹眹鍩勯崹閬嶆偤閺囶澁缍栭柛鈩冪⊕閳锋帗銇勯弴妤€浜惧銈忕秶閹凤拷
濠电偛顕慨顓㈠磻閹炬枼妲堥柡鍌濇硶婢ф稒淇婇懠顒夆偓婵嬫煟閵忊晛鐏查柟鍑ゆ嫹
濠电姷顣介埀顒€鍟块埀顒勵棑缁辩偛顓兼径瀣閻庣懓瀚竟鍡欐崲娑斾線鏌i姀鈺佺伈闁瑰嚖鎷�
濠电姷顣介埀顒€鍟块埀顒勵棑缁辩偛顓兼径濠勵吋闂佽鍨庨崟顓фК闂佽閰eḿ褍螞濞戙垺鍋夐柨鐕傛嫹
闂備胶枪缁绘劙骞婃惔銊ョ劦妞ゆ帒鍊哥敮鍫曞箹鐎涙ḿ鐭掔€规洘绻堥弫鎾绘晸閿燂拷
闂備胶枪缁绘劙骞婃惔銊ョ劦妞ゆ巻鍋撻柛姘儑缁﹪鏁傞崜褏鐓撻柣搴岛閺呮繈鎯屽▎鎴犵=濞撴艾锕ョ€氾拷
闂備浇銆€閸嬫挻銇勯弽銊р槈闁伙富鍣i弻娑樷攽閹邦亞鑳虹紓浣靛妽濡炶棄顕i妸鈺婃晬婵炲棙鍨电粭锟犳⒑閸濆嫬鈧骞婇幘鑸殿潟闁跨噦鎷�
闂備礁鎼崯鐗堟叏妞嬪海绀婂鑸靛姈閻擄綁鎮规潪鎷岊劅婵炲眰鍊曢湁闁挎繂妫欑粈鈧梺鍛娚戦悧鐘茬暦閹扮増鏅搁柨鐕傛嫹
婵犵妲呴崹顏堝礈濠靛棭鐔嗘俊顖氬悑鐎氱粯銇勯幘瀵哥畺閻庢熬鎷�
濠电姷顣介埀顒€鍟块埀顒勵棑缁辩偛顓奸崶銊ヮ伕濡炪倖鎸荤换鍐偓姘虫珪娣囧﹪顢涘Δ鈧晶鍙夌節椤喗瀚�
婵犵妲呴崹顏堝礈濠靛棭鐔嗘慨妞诲亾鐎规洦鍓熼、娆撳礂閻撳簶鍋撻悽鍛婄厸闁割偅绻勫瓭婵犳鍣幏锟�
婵犵妲呴崹顏堝礈濠靛棭鐔嗘慨妞诲亾闁哄苯鎳橀崺鈧い鎺嗗亾闁宠閰i獮鎴﹀箛闂堟稒顔嗛梻浣告惈鐎氭悂骞忛敓锟�
婵犵妲呴崹顏堝礈濠靛棭鐔嗘慨妞诲亾鐎规洩缍侀獮瀣攽閸偂绱�
濠电姷顣介埀顒€鍟块埀顒勵棑缁辩偛顓兼径濠勭厬闂佺懓鐡ㄧ换鍕敂鐎涙ü绻嗘い鏍殔婢у弶绻濋~顔藉
闂佽楠搁崢婊堝礈濠靛鍋嬮柟鎯版閻鈹戦悩鎻掓殭闁奸潧缍婇弻銈夋嚍閵夈儱顫嶉梺缁樼壄缂嶄礁鐣峰▎鎾存櫢闁跨噦鎷�
UB闂備礁婀辩划顖炲礉濡ゅ懐宓侀柛銉㈡櫆鐎氭岸鎮楀☉娅虫垿锝為敓锟�
闂備浇澹堟ご绋款潖婵犳碍鐒鹃悗鐢电《閸嬫捇鐛崹顔句痪濠电姭鍋撻柨鐕傛嫹
闂佽楠哥粻宥夊垂閸濆嫸鑰块柛銏㈠殰
闂備礁鎲″缁樻叏妞嬪海绀婂璺虹灱閸楁碍绻涢崱妤€顒㈤柛鐐差槹缁绘稓绱欓悩鍝勫帯闂佺ǹ楠忛幏锟�
缂傚倸鍊烽悞锕傛偡閿曞倸鍨傛繝濠傚椤╅攱銇勯幒宥囶槮缂佹彃婀遍埀顒傚仯閸婃繄绱撳棰濇晩闁跨噦鎷�
©2017 www.mb5u.com婵犵妲呴崹顏堝礈濠靛棭鐔嗘慨妞诲亾鐎殿噮鍣i幃鈺呭箵閹烘挸鐦�
闂備浇銆€閸嬫捇鏌熼婊冾暭妞ゃ儻鎷�&闂備礁鎲$敮鎺懳涢弮鍫燁棅闁跨噦鎷�