程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> PHP綜合 >> php設計模式介紹之注冊模式

php設計模式介紹之注冊模式

編輯:PHP綜合

我們通常認為避免使用全局變量是一種好的選擇,因此,對象經常被作為參數從一段代碼傳遞到另一 段。但是傳遞實例的一個問題就是對象有時候不知道將要傳遞給誰——?經過一個函數後才被 傳遞到真正需要這個對象的函數。

為了編寫,閱讀,修改代碼的方便,最好能夠減少不同對象的 數量,並且能夠將大量廣泛使用的對象統一表示為一個單一,常用的對象。

問題:

你如何 通過單一的全局的對象來獲取對其它對象的引用?

解決方案:

“注冊模式” 就像“對象的電話簿”——儲存並且能夠取回對對象引用的登記簿。(注:PHP中 的“聯合數組”也起到了類似“電話簿”的功能。事實上,“注冊模式 ”就是圍繞PHP中強大的數組完成的。)“注冊模式”的一些特性經常被包含在“ 單一模式”中(參見第四章),使得“注冊模式”成為你整個應用信息的決定性來源。

注釋:“注冊模式”類主要參考了Martin Fowlerdescribes用Java語言實現的 Patterns of EntERPrise Application Architecture(企業應用程序體系結構模型)。Marcus Baker謝 了一篇詳細的PHP中應用“注冊模式”的文章。該文章可在PHPPatterns.com的站點獲的 (http://www.PHPpatterns.com/index.PHP/article/articleview/75/1/1/)。Baker也涉及了一些測試 considerations,示范了測試驅動的開發方法。

樣本代碼:

正如Martin Flower在他的 “注冊模式”一文中提及的樣本代碼所示,你可以用各種方法,提供各種接口實現“注 冊模式”。讓我們仔細探究這種想法,並建立PHP4中的“注冊模式”的一些不同實現。

讓我們以編寫能儲存並恢復對象實例並能對“注冊模式”提供全局訪問的代碼開始。 這個類的實例變量能夠緩存對象,並且“注冊模式”本身是一個“單一模式”。 像以前一樣,測試決定需求。我們的第一個測試要確定“注冊模式”是一個“單件模式 ”類。

// PHP4

class ReGIStryPHP4TestCase extends UnitTestCase {
function testRegistryIsSingleton() {
$this->assertIsA($reg =& Registry::getInstance(), ‘Registry’);
$this->assertReference($reg, Registry::getInstance());
}
}

這裡,要把你在以前幾章“單件模式 ”中學到的知識用上,你應該能夠很快寫出能夠通過該測試的類。以下是一個滿足測試要求的 “注冊模式”類(ignoring the code required to enforce no direct object creation):

class Registry {
function &getInstance() {
static $instance = array();
if (!$instance) $instance[0] =& new Registry;
return $instance [0];
}
}

一個簡單的靜態數組就足夠記錄這個單一實例了。

接下來, 讓我們轉到“注冊模式”獨特的特性上面。一個“注冊模式”應該提供get() 和 set()方法來存儲和取得對象(用一些屬性key)而且也應該提供一個isValid()方法來確定一個給定的屬 性是否已經設置。

這三個方法的一個簡單實現在接下來討論。這裡是兩個isValid():方法的測試 方法。

代碼:

class RegistryPHP4TestCase extends UnitTestCase
{function testRegistryIsSingleton() { /*...*/ }
function testEmptyRegistryKeyIsInvalid()
{$reg =& Registry::getInstance();
$this- >assertFalse($reg->isValid('key'));
}
function testEmptyRegistryKeyReturnsNull()
{$reg =& Registry::getInstance();
$this- >assertNull($reg->get('key'));
}
}

作者注: assertFalse()

assertFalse()僅僅是assertTrue()的反面,如果第一個參數預期是PHP中的布爾 值false,測試通過。

通過基於測試驅動的開發方式,你可以編寫盡可能少的代碼來符合你現階 段的測試需求,你也可以增加測試——如果你還未滿足這個類的需求。

以下為滿足前 述測試要求的最簡單的代碼:

代碼:

class ReGIStry
{function isValid() {return false;}
function get() {}
function &getInstance()
{static $instance = array();
if (!$instance) $instance[0] =& new Registry;
return $instance[0];
}
}

確實,isValid() 和 get()方法的代碼片斷並不是非常好 ,但是所有的測試通過了!下面我們添加更豐富的測試用例。

代碼:

class RegistryPHP4TestCase extends UnitTestCase
{function testRegistryIsSingleton() { /*...*/ }
function testEmptyRegistryKeyIsInvalid() { /*...*/ }
function testEmptyRegistryKeyReturnsNull() { /*...*/ }
function testSetRegistryKeyBecomesValid ()
{$reg =& Registry::getInstance();
$test_value = 'something';$reg- >set('key', $test_value);
$this->assertTrue($reg->isValid ('key'));
}
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved