php設(shè)計(jì)模式介紹之值對(duì)象模式第2/5頁(yè)
更新時(shí)間:2008年04月13日 22:10:17 作者:
在所有的最簡(jiǎn)單的程序中,大多數(shù)對(duì)象都有一個(gè)標(biāo)識(shí),一個(gè)重要的商業(yè)應(yīng)用對(duì)象,例如一個(gè)Customer或者一個(gè)SKU,有一個(gè)或者更多的屬性---id,name,email地址,這樣可以把它從同一個(gè)類的其他實(shí)例區(qū)分開(kāi)來(lái)。此外,對(duì)象有一個(gè)恒定的標(biāo)識(shí):它是貫穿于整個(gè)應(yīng)用程序的一個(gè)唯一的標(biāo)識(shí),對(duì)于程序員來(lái)說(shuō),”customer A”在任何地方就是”customer A”,并且只要你的程序在持續(xù)運(yùn)行時(shí)"customer A"仍然是"customer A"。 但是一個(gè)對(duì)象不需要有一個(gè)標(biāo)識(shí)。有些對(duì)象僅僅是為了描述其他對(duì)象的屬性。
問(wèn)題:
那么,你該如何為Date或Dollar這樣一些描述簡(jiǎn)單的應(yīng)用定義一個(gè)高效的類,并且易于創(chuàng)建呢。
解決方案:
高效的對(duì)象應(yīng)該像PHP的整型那樣運(yùn)作:如果你把同一個(gè)對(duì)象資源賦值給兩個(gè)不同的變量,然后改變其中的一個(gè)變量,另一個(gè)變量仍然不受影響。事實(shí)上,這就是Value Object模式的目標(biāo)所在。
執(zhí)行Value Object時(shí),php4和php5是有區(qū)別的。
正如以上你所看到的,PHP5通過(guò)new進(jìn)行對(duì)象資源的賦值傳遞的是對(duì)象資源的指針就像我們?cè)赑HP4中通過(guò)指針傳遞一樣。很明顯,這是一個(gè)問(wèn)題。為了解決那個(gè)問(wèn)題并實(shí)現(xiàn)一個(gè)專有對(duì)象Dollar的值,我們必須使屬性$amount的對(duì)象的所有屬性的一個(gè)值在一般情況下不可變或不能改變。但是在PHP語(yǔ)言的沒(méi)有提供參數(shù)不可改變的功能的情況下,你完全可以結(jié)合屬性的可見(jiàn)性與獲得和設(shè)置方法來(lái)實(shí)現(xiàn)。
相反地,PHP4操作所有的對(duì)象都是遵循Value Objects對(duì)象規(guī)律的,因?yàn)镻HP4的賦值操作相當(dāng)于對(duì)對(duì)象做了一個(gè)拷貝。所以為了在PHP4中實(shí)現(xiàn)Value Objects設(shè)計(jì)模式你需要打破你細(xì)心地培養(yǎng)的通過(guò)指針賦值來(lái)創(chuàng)建、傳遞、提取對(duì)象的習(xí)慣。
注:術(shù)語(yǔ) 不可變的(Immutable):
在詞典中Immutable的定義是不允許或不易受影響。在編程中,這個(gè)術(shù)語(yǔ)表示一個(gè)一旦被設(shè)置就不能改變的值。
PHP5 樣本代碼:
既然我們開(kāi)始用PHP5編寫(xiě)代碼,讓我們優(yōu)化一個(gè)PHP5的Value Object的實(shí)例并創(chuàng)建一個(gè)較好的Dollar類定義。命名在面向?qū)ο缶幊讨蟹浅V匾x擇一個(gè)唯一的貨幣類型作為這個(gè)類的名字,說(shuō)明它不被定義為可以處理多種貨幣類型的類。
class Dollar {
protected $amount;
public function __construct($amount=0) {
$this->amount = (float)$amount;
}
public function getAmount() {
return $this->amount;
}
public function add($dollar) {
return new Dollar($this->amount + $dollar->getAmount());
}
}
類里面的屬性如果加上protected前綴,別的類是訪問(wèn)不了的。protected(和private)拒絕通過(guò)屬性直接被訪問(wèn)。
通常,當(dāng)你使用面向?qū)ο筮M(jìn)行編程的時(shí)候,你經(jīng)常需要?jiǎng)?chuàng)建了一個(gè)“setter”函數(shù),就類似于:
public setAmount($amount)
{
$this->amount=$amount;
}
一樣,在這種情況下,雖然沒(méi)有設(shè)定函數(shù)Dollar::amount(),但在對(duì)象的實(shí)例化期時(shí),參數(shù)Dollar::amount就已經(jīng)被賦值了。而函數(shù)Dollar::getAmount()只是提供一個(gè)訪問(wèn)Dollar屬性的功能,在這里訪問(wèn)的數(shù)據(jù)類型為浮點(diǎn)型。
最有趣的變化是在Dollar::add()方法函數(shù)中。并不是直接改變$this->amount變量的值從而會(huì)改變已存在的Dollar對(duì)象實(shí)例,而是創(chuàng)建并返回一個(gè)新的Dollar實(shí)例?,F(xiàn)在,盡管你指定當(dāng)前對(duì)象給多個(gè)變量,但是每一個(gè)變量的變化都不會(huì)影響其它的變量實(shí)例。
對(duì)于價(jià)值設(shè)計(jì)模式不變性是關(guān)鍵,任何對(duì)于一個(gè)Value Object的變量amount的改變,是通過(guò)創(chuàng)建一個(gè)新的帶有不同預(yù)期值的類的實(shí)例來(lái)完成的。上文中提高的最初那個(gè)$this->amount變量的值從未改變。
簡(jiǎn)單來(lái)說(shuō),在PHP5里面使用價(jià)值設(shè)計(jì)模式時(shí),需要注意以下幾個(gè)方面:
保護(hù)值對(duì)象的屬性,禁止被直接訪問(wèn)。
在構(gòu)造函數(shù)中就對(duì)屬性進(jìn)行賦值。
去掉任何一個(gè)會(huì)改變屬性值的方式函數(shù)(setter),否則屬性值很容易被改變。
以上三步創(chuàng)建了一個(gè)不變的值,這個(gè)值一旦被初始化設(shè)置之后就不能被改變。當(dāng)然,你也應(yīng)該提供一個(gè)查看函數(shù)或者是訪問(wèn)Value Object的屬性的方法,并且可以添加一些與這個(gè)類相關(guān)的函數(shù)。值對(duì)象并不是只能用在一個(gè)簡(jiǎn)單的架構(gòu)上,它也可以實(shí)現(xiàn)重要的商務(wù)邏輯應(yīng)用。讓我們看看下一個(gè)例子:
您可能感興趣的文章:
- php設(shè)計(jì)模式 Observer(觀察者模式)
- php設(shè)計(jì)模式 Singleton(單例模式)
- php設(shè)計(jì)模式 Command(命令模式)
- php設(shè)計(jì)模式 Composite (組合模式)
- php設(shè)計(jì)模式 Bridge (橋接模式)
- php設(shè)計(jì)模式 Chain Of Responsibility (職責(zé)鏈模式)
- php設(shè)計(jì)模式 Mediator (中介者模式)
- php設(shè)計(jì)模式 Prototype (原型模式)代碼
- php設(shè)計(jì)模式 Command(命令模式)
- 介紹php設(shè)計(jì)模式中的工廠模式
- php設(shè)計(jì)模式介紹之編程慣用法
- php設(shè)計(jì)模式 Strategy(策略模式)
- php設(shè)計(jì)模式 FlyWeight (享元模式)
- php設(shè)計(jì)模式 State (狀態(tài)模式)
- php設(shè)計(jì)模式 Proxy (代理模式)
- php設(shè)計(jì)模式 Template (模板模式)
相關(guān)文章
PHP運(yùn)行SVN命令顯示某用戶的文件更新記錄的代碼
使用SVN開(kāi)發(fā)者們平時(shí)開(kāi)發(fā)或代碼上線過(guò)程中需要知道某個(gè)時(shí)間段內(nèi)修改或添加過(guò)那些文件,所以用PHP寫(xiě)了個(gè)小程序,直接在瀏覽器中調(diào)用即可2014-01-01
php日志函數(shù)error_log用法實(shí)例分析
這篇文章主要介紹了php日志函數(shù)error_log用法,結(jié)合實(shí)例形式分析了php日志函數(shù)error_log相關(guān)的配置文件設(shè)置、函數(shù)功能、用法與使用注意事項(xiàng),需要的朋友可以參考下2019-09-09
網(wǎng)站用php實(shí)現(xiàn)paypal整合方法
雖然在中國(guó)paypal不是很流行,但如果把范圍擴(kuò)大到世界的話,那paypal無(wú)疑就是老大了。2010-11-11
微信公眾號(hào)點(diǎn)擊菜單即可打開(kāi)并登錄微站的實(shí)現(xiàn)方法
這篇文章主要介紹了微信公眾號(hào)點(diǎn)擊菜單即可打開(kāi)并登錄微站的實(shí)現(xiàn)方法,以實(shí)例形式對(duì)回調(diào)、菜單及參數(shù)的處理等具體實(shí)現(xiàn)步驟與功能代碼都做了較為詳細(xì)的描述,對(duì)于微信公眾號(hào)的開(kāi)發(fā)來(lái)說(shuō)具有很好的參考借鑒價(jià)值,需要的朋友可以參考下2014-11-11
php操作sqlserver關(guān)于時(shí)間日期讀取的小小見(jiàn)解
以前一直在用mysql對(duì)sqlserver不是很熟悉,于是摸著石頭過(guò)河。沒(méi)有別的至少mysql和sqlserver還算是親戚 做條件查詢的時(shí)候。出現(xiàn)了問(wèn)題2009-11-11
Php獲取金書(shū)網(wǎng)的書(shū)名的實(shí)現(xiàn)代碼
php獲取金書(shū)網(wǎng)的書(shū)名的實(shí)現(xiàn)代碼。2010-06-06

