最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

php設計模式介紹之值對象模式第5/5頁

 更新時間:2008年04月13日 22:10:17   作者:  
在所有的最簡單的程序中,大多數(shù)對象都有一個標識,一個重要的商業(yè)應用對象,例如一個Customer或者一個SKU,有一個或者更多的屬性---id,name,email地址,這樣可以把它從同一個類的其他實例區(qū)分開來。此外,對象有一個恒定的標識:它是貫穿于整個應用程序的一個唯一的標識,對于程序員來說,”customer A”在任何地方就是”customer A”,并且只要你的程序在持續(xù)運行時"customer A"仍然是"customer A"。 但是一個對象不需要有一個標識。有些對象僅僅是為了描述其他對象的屬性。

PHP4樣本代碼:

和PHP5不一樣的是,PHP4賦值對象資源的時候是拷貝該對象,這個語法的特點本質上和值對象設計模式要求正好吻合。

然而,PHP4不能控制的屬性和方法函數(shù)在對象之外的可見性,所以實現(xiàn)一個值對象設計模式相對PHP5也有細微的差別。

假如你回想一下這本書序言中的“對象句柄”部分,它提出了三個 “規(guī)則”,當你在PHP4中使用對象去模仿PHP5中的對象句柄時,這三個規(guī)則總是適用的:

通過指針($obj=&new class;)來創(chuàng)建對象。 
用指針(function funct(&$obj) param{})來傳遞對象。 
用指針(function &some_funct() {} $returned_obj =& some_funct())來獲取一個對象。
然后,值對象設計模式卻不能使用上述三個“總是適用”的規(guī)則。只有忽視了這些規(guī)則,才能總是得到一個PHP4對象的拷貝(這相當于PHP5中的“克隆”操作,描述在http://www.php.net/manual/en/language.oop5.cloning.php)

因為PHP4可以輕松地賦值一個對象—這在PHP語言中是一個固有的行為,所以實現(xiàn)變量的不可更改就需要通過值對象通用協(xié)定來實現(xiàn)。在PHP4中,如果要使用值對象,請不要通過指針來創(chuàng)建或獲取一個對象,并且給所有需要保護以免外界修改的屬性或者方法函數(shù)命名時,都在屬性和方法函數(shù)的名字加上下劃線(_)做前綴。按照協(xié)定,變量如果具有值對象的屬性,應該使用一個下劃線來標識它的私有性。

下面是PHP4中的Dollar類:


// PHP4
class Dollar {
var $_amount;
function Dollar($amount=0) {
$this->_amount = (float)$amount;
}
function getAmount() {
return $this->_amount;
}
function add($dollar) {
return new Dollar($this->_amount + $dollar->getAmount());
}
function debit($dollar) {
return new Dollar($this->_amount - $dollar->getAmount());
}
}
下面這個實例可以說明,你不能在PHP4中限制一個屬性只能被外部更改:

function TestChangeAmount() {
$d = new Dollar(5);
$this->assertEqual(5, $d->getAmount());
//only possible in php4 by not respecting the _private convention
$d->_amount = 10;
$this->assertEqual(10, $d->getAmount());
}
再重復一次,在所有PHP4對象中,私有變量的前綴使用一個下劃線,但是你還是可以從外部來直接訪問私有屬性和方法函數(shù)。 

值對象中的商業(yè)邏輯

值對象(Value Objects)不僅僅用于最小限度的訪問方法這樣的簡單的數(shù)據(jù)結構,它同樣還可以包括有價值的商業(yè)邏輯??紤]以下你如果實現(xiàn)許多人中平均分配金錢。

如果總錢數(shù)確實是可以分成整數(shù),你可以生成一組Dollar對象,而且每一個Dollar對象都擁有相同的部分。但是當總數(shù)可以整數(shù)的美元或者美分的時候,我們該怎么處理呢?

讓我們開始用一個簡單的代碼來測試一下:

// PHP5
function testDollarDivideReturnsArrayOfDivisorSize() {
$full_amount = new Dollar(8);
$parts = 4;
$this->assertIsA(
$result = $full_amount->divide($parts)
,'array');
$this->assertEqual($parts, count($result));
}
注釋 assertIsA:

assertIsA()的作用是讓你測試:一個特定的變量是否屬于一個實例化的類。當然你也可以用它來驗證變量是否屬于一些php類型:字符串、數(shù)字、數(shù)組等。

為了實現(xiàn)上述測試, Dollar::divide()方法函數(shù)的編碼如下…

public function divide($divisor) {
return array_fill(0,$divisor,null);
}
最好加上更多的細節(jié)。

function testDollarDrivesEquallyForExactMultiple() {
$test_amount = 1.25;
$parts = 4;
$dollar = new Dollar($test_amount*$parts);
foreach($dollar->divide($parts) as $part) {
$this->assertIsA($part, ‘Dollar');
$this->assertEqual($test_amount, $part->getAmount());
}
}
現(xiàn)在,應當返回存有正確數(shù)據(jù)的Dollar對象,而不是簡單的返回數(shù)量正確的數(shù)組。

實現(xiàn)這個仍然只需要一行語句:


public function divide($divisor) {

return array_fill(0,$divisor,new Dollar($this->amount / $divisor));
最后一段代碼需要解決一個除數(shù)不能把Dollar的總數(shù)均勻的除開的問題。

這是一個棘手的問題:如果存在不能均勻除開的情況,是第一部分還是最后一部分能得到一個額外的金額(便士)?怎樣獨立測試這部分的代碼?

一個方法是:明確指定代碼最后需要實現(xiàn)目標:這個數(shù)組的元素數(shù)量應該是與除數(shù)表示的數(shù)量相等的,數(shù)組的元素之間的差異不能大于0.01,并且所有部分的總數(shù)應該與被除之前的總數(shù)的值是相等的。

上面的描述通過正如下面的代碼實現(xiàn):

function testDollarDivideImmuneToRoundingErrors() {
$test_amount = 7;
$parts = 3;
$this->assertNotEqual( round($test_amount/$parts,2),
$test_amount/$parts,
'Make sure we are testing a non-trivial case %s');
$total = new Dollar($test_amount);
$last_amount = false;
$sum = new Dollar(0);
foreach($total->divide($parts) as $part) {
if ($last_amount) {
$difference = abs($last_amount-$part->getAmount());
$this->assertTrue($difference <= 0.01);
}
$last_amount = $part->getAmount();
$sum = $sum->add($part);
}
$this->assertEqual($sum->getAmount(), $test_amount);
}
注釋 assertNotEqual:

當你要確保兩個變量的值是不相同時,你可以用它來進行檢驗。這里面的值相同是PHP的”==”運算符進行判斷的。任何情況下當你需要確保兩個變量的值是不相同的時候,你就可以使用它。

現(xiàn)在根據(jù)上述代碼,如果來構造Dollar::divide()方法函數(shù)呢?

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());
}
public function debit($dollar) {
return new Dollar($this->amount - $dollar->getAmount());
}
public function divide($divisor) {
$ret = array();
$alloc = round($this->amount / $divisor,2);
$cumm_alloc = 0.0;
foreach(range(1,$divisor-1) as $i) {
$ret[] = new Dollar($alloc);
$cumm_alloc += $alloc;
}
$ret[] = new Dollar(round($this->amount - $cumm_alloc,2));
return $ret;
}
}
這段代碼可以正常運行,但是仍然有一些問題,考慮一下如果在testDollarDivide()的開始處改變$test_amount 為 0.02; $num_parts 為 5;這樣的臨界條件,或者考慮一下當你的除數(shù)不是一個整型數(shù)字,你該怎么做?

解決上邊這些問題的方法是什么呢?還是使用測試導向的開發(fā)循環(huán)模式:增加一個需求實例,觀察可能的錯誤,編寫代碼來生成一個新的實例進行運行,還有問題存在時繼續(xù)分解。最后重復上述過程。

相關文章

  • 8個PHP數(shù)組面試題

    8個PHP數(shù)組面試題

    這篇文章主要介紹了8個PHP數(shù)組面試題,例如寫函數(shù)創(chuàng)建長度為10的數(shù)組,數(shù)組中的元素為遞增的奇數(shù),首項為1、創(chuàng)建長度為10的數(shù)組,數(shù)組中的數(shù)為遞增的等比數(shù),比值為3,首項為等題目,需要的朋友可以參考下
    2015-06-06
  • PHP中session使用方法詳解

    PHP中session使用方法詳解

    在PHP開發(fā)中對比起Cookie,session 是存儲在服務器端的會話,相對安全,并且不像 Cookie 那樣有存儲長度限制,本文簡單介紹 session 的使用
    2007-03-03
  • PHP運行SVN命令顯示某用戶的文件更新記錄的代碼

    PHP運行SVN命令顯示某用戶的文件更新記錄的代碼

    使用SVN開發(fā)者們平時開發(fā)或代碼上線過程中需要知道某個時間段內修改或添加過那些文件,所以用PHP寫了個小程序,直接在瀏覽器中調用即可
    2014-01-01
  • 淺談PHP中Stream(流)

    淺談PHP中Stream(流)

    Stream是PHP開發(fā)里最容易被忽視的函數(shù)系列(SPL系列,Stream系列,pack函數(shù),封裝協(xié)議)之一,但其是個很有用也很重要的函數(shù)。Stream可以翻譯為“流”,在Java里,流是一個很重要的概念。
    2015-06-06
  • php日志函數(shù)error_log用法實例分析

    php日志函數(shù)error_log用法實例分析

    這篇文章主要介紹了php日志函數(shù)error_log用法,結合實例形式分析了php日志函數(shù)error_log相關的配置文件設置、函數(shù)功能、用法與使用注意事項,需要的朋友可以參考下
    2019-09-09
  • 網(wǎng)站用php實現(xiàn)paypal整合方法

    網(wǎng)站用php實現(xiàn)paypal整合方法

    雖然在中國paypal不是很流行,但如果把范圍擴大到世界的話,那paypal無疑就是老大了。
    2010-11-11
  • 微信公眾號點擊菜單即可打開并登錄微站的實現(xiàn)方法

    微信公眾號點擊菜單即可打開并登錄微站的實現(xiàn)方法

    這篇文章主要介紹了微信公眾號點擊菜單即可打開并登錄微站的實現(xiàn)方法,以實例形式對回調、菜單及參數(shù)的處理等具體實現(xiàn)步驟與功能代碼都做了較為詳細的描述,對于微信公眾號的開發(fā)來說具有很好的參考借鑒價值,需要的朋友可以參考下
    2014-11-11
  • php操作sqlserver關于時間日期讀取的小小見解

    php操作sqlserver關于時間日期讀取的小小見解

    以前一直在用mysql對sqlserver不是很熟悉,于是摸著石頭過河。沒有別的至少mysql和sqlserver還算是親戚 做條件查詢的時候。出現(xiàn)了問題
    2009-11-11
  • Php獲取金書網(wǎng)的書名的實現(xiàn)代碼

    Php獲取金書網(wǎng)的書名的實現(xiàn)代碼

    php獲取金書網(wǎng)的書名的實現(xiàn)代碼。
    2010-06-06
  • 兼容PHP5的PHP目錄管理函數(shù)庫

    兼容PHP5的PHP目錄管理函數(shù)庫

    php下進行目錄的一些操作,經(jīng)常用到的方法
    2008-07-07

最新評論

江口县| 乐山市| 渝北区| 措勤县| 阳春市| 金沙县| 封丘县| 凌云县| 金门县| 鹤峰县| 马关县| 镇原县| 乌拉特后旗| 区。| 柘荣县| 江北区| 侯马市| 永德县| 青海省| 阿合奇县| 朝阳市| 西和县| 崇左市| 保定市| 和田市| 崇阳县| 印江| 光泽县| 汉寿县| 襄垣县| 湾仔区| 阳春市| 沈阳市| 武川县| 乌兰浩特市| 高碑店市| 邛崃市| 通化县| 丁青县| 谷城县| 灵璧县|