日韩天天综合网_野战两个奶头被亲到高潮_亚洲日韩欧美精品综合_av女人天堂污污污_视频一区**字幕无弹窗_国产亚洲欧美小视频_国内性爱精品在线免费视频_国产一级电影在线播放_日韩欧美内地福利_亚洲一二三不卡片区

《PHP設(shè)計模式介紹》第三章 工廠模式(6)_PHP教程

編輯Tag賺U幣
教程Tag:暫無Tag,歡迎添加,賺取U幣!

推薦:《PHP設(shè)計模式介紹》第二章 值對象模式
在所有的最簡單的程序中,大多數(shù)對象都有一個標識,一個重要的商業(yè)應(yīng)用對象,例如一個Customer或者一個SKU,有一個或者更多的屬性---id,name,email地址,這樣可以把它從同一個類的其他實例區(qū)分開

“工廠”促進多態(tài)

控制被送回對象的內(nèi)在狀態(tài)固然重要, 但是如果促進多態(tài)即返回相同的接口多種類的對象,可以使得工廠模式的功能更為強大。

讓我們再次看一下Monopoly的例子,然后執(zhí)行購買游戲中的道具的行為。在游戲中,你的任務(wù)就是買道具,包括一些基本動作。更進一步說, 有三種不同的道具: Street,RailRoad和Utility。所有三個類型的道具有一些共同點: 每個道具都被一個玩家擁有; 每個都有價格;而且每個都能為它的擁有者產(chǎn)生租金只要其他的玩家在它上面登陸。但道具之間還是存在差異的,舉例來說, 計算租金的多少就取決于道具的類型。

下列的代碼展示了一個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() 方法都被聲明為基類。

注:術(shù)語 – 基類
一個基類就是不能被直接實例化的類。 一個基礎(chǔ)的類包含一個或更多的基礎(chǔ)方法,這些方法必須在子類被覆蓋。一旦所有的抽象方法被覆蓋了, 子類也就產(chǎn)生了。
基類為許多相似的類創(chuàng)造了好的原型。
CalcRent() 方法必須在子類被覆蓋,從而形成一個具體的類。因此, 每個子類包括:Street,RailRoad和Utility,和必須定義的calcRent() 方法。

為實現(xiàn)以上的情況,這三個類可以定義為:

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() 方法。隨著所有的基礎(chǔ)方法都被定義, 每個子類都被實例化了。

為了開始游戲, 所有的Monopoly道具必須被創(chuàng)建起來。因為這章是介紹工廠模式的,所有Property的類型存在很多共性,你應(yīng)該想到多態(tài)性,從而建立所有需要的對象。

我們還是以道具工廠類開始。 在我住的地方,政府的Assessor(定稅人)掌握了稅務(wù)和契約, 因此我命名它為的道具定稅工廠。下一步,這個工廠將制造全部的專有道具。在真正應(yīng)用時,所有的Monopoly道具的數(shù)值可能都取自于一個數(shù)據(jù)庫或者一個文本, 但是對于這一個例子來說, 可以僅僅用一個數(shù)組來代替:

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道具�,F(xiàn)在,我們只是簡單的用一個函數(shù)定義實例化變量$game,那么再把它加入Assessor類好了。

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

也許你會偏向于選擇使用數(shù)據(jù)庫記錄數(shù)據(jù),不會用數(shù)組, 因為有一大堆的參數(shù)不可避免地要被羅列。如果是這樣的話,可以考慮使用" 引入叁數(shù)對象 " 進行重構(gòu)。

注:重構(gòu)-引入叁數(shù)對象
方法中如果有很多參數(shù),常常變得很復雜,而且容易導致錯誤。你可以引入一個封裝參數(shù)的對象來替代一大堆的參數(shù)。舉例來說,“start date” and “end date” 叁數(shù)可以用一個 DateRange 對象一起代替。

在Monopoly這個例子中,這個參數(shù)對象應(yīng)該是什么呢?PropertyInfo,怎樣?它的目的是使每個道具參數(shù)數(shù)組引入 PropertyInfo 類的構(gòu)造器中,然后返回一個新對象。目的就意味著設(shè)計, 依照 TDD, 那意味著一個測試情形。

分享:《PHP設(shè)計模式介紹》第一章 編程慣用法
學習一門新的語言意味著要采用新的慣用法。這章將介紹或者可能重新強調(diào)一些慣用法。你會發(fā)現(xiàn)這些慣用法在你要在代碼中實現(xiàn)設(shè)計模式時候是非常有用的。 在這里總結(jié)的許多編程慣用法都是很值得

來源:模板無憂//所屬分類:PHP教程/更新時間:2008-08-22
相關(guān)PHP教程