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

《PHP設(shè)計(jì)模式介紹》第六章 偽對(duì)象模式(2)_PHP教程

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

推薦:《PHP設(shè)計(jì)模式介紹》第五章 注冊(cè)模式
我們通常認(rèn)為避免使用全局變量是一種好的選擇,因此,對(duì)象經(jīng)常被作為參數(shù)從一段代碼傳遞到另一段。但是傳遞實(shí)例的一個(gè)問題就是對(duì)象有時(shí)候不知道將要傳遞給誰——?經(jīng)過一個(gè)函數(shù)后才被傳

具備了這個(gè)思想,讓我們看看如何封裝$_SESSION之類的全局變量。

class Session {
function Session() {
$this->init();
}
function init() {
if (!isset($_SESSION)) {
if (headers_sent()) {
trigger_error(
‘Session not started before creating session object’);
} else {
session_start();
}
}
}
function isValid($key) {
return array_key_exists($key, $_SESSION);
}
function get($key) {
return (array_key_exists($key, $_SESSION))
? $_SESSION[$key]
: null;
}
function set($key, $value) {
$_SESSION[$key] = $value;
}
function clear($key) {
nset($_SESSION[$key]);
}
}

類Session封裝了全局變量$_SESSION。對(duì)類SESSION的測(cè)試非常類似于對(duì)前期的已注冊(cè)的類的改良測(cè)試(參見第5章),但是卻無任何通過參數(shù)獲得或設(shè)置相應(yīng)值的意圖。

你也許注意到了構(gòu)造函數(shù)調(diào)用了Session::init()方法。為什么這個(gè)方法不是構(gòu)造函數(shù)的一部分呢?這樣分開的好處是你能靜態(tài)調(diào)用它并確保session已經(jīng)開始。下面是一個(gè)如何使用該類的例子。

Session::init();
$page =& new PageDirector(new Session);

大部分測(cè)試方面的文獻(xiàn)很推崇偽對(duì)象并建議你親自寫一個(gè)。如果你打算那樣做,開始測(cè)試時(shí)你就只需要充實(shí)那些你需要的方法就可以了。譬如,一個(gè)用于處理代碼的ServerStub的Session類很可能是這樣的:

class MyMockSessionUser1 {
function isValid($key) {
return (‘user_id’ == $key) ? true : false;
}
function get($key) {
if (‘user_id’ == $key) {
return 1;
}
}
}

幸運(yùn)的是,你可以用SimpleTest來避免那些易范的錯(cuò)誤。Mock::generate()方法允許你創(chuàng)建一個(gè)類來實(shí)例化或動(dòng)態(tài)地配置你想要的結(jié)果。

注:偽對(duì)象技術(shù)

SimpleTest所使用的方法僅是偽對(duì)象的多種用法之一。偽對(duì)象的代碼傳遞是另一種。隨著PHP5的到來,你也許能看到偽對(duì)象以對(duì)象中的__call()方法來執(zhí)行。

以下是如何用SimpleTest生成的偽對(duì)象來測(cè)試并重構(gòu)MyMockSessionUser1類(如上例中)。

Mock::Generate(‘Session’);
class PageDirectorTestCase extends UnitTestCase {
function testSomethingWhichUsesSession() {
$session =& new MockSession($this);
$session->setReturnValue(‘isValid’, true);
$session->setReturnValue(‘get’, 1);
// ...
}
}

更進(jìn)一步說,你能隨心所欲的設(shè)置何種方法被調(diào)用以及調(diào)用多少次。你甚至可以驗(yàn)證那些根本不該被調(diào)用的方法。
下面是一個(gè)擴(kuò)展型的測(cè)試,它用來建立和驗(yàn)證那些復(fù)雜的設(shè)計(jì)。

class PageDirectorTestCase extends UnitTestCase {
function testSomethingWhichUsesSession() {
$session =& new MockSession($this);
$session->setReturnValue(‘isValid’, true);
$session->setReturnValue(‘get’, 1);
$session->expectOnce(‘isValid’, array(‘user_id’));
$session->expectOnce(‘get’, array(‘user_id’));
$session->expectNever(‘set’);
// the actual code which uses $session
$session->tally();
}
}

使用偽對(duì)象的原因很多,方法也多樣化。但在我們繼續(xù)前,讓我們把另外的一些類加入進(jìn)來,使其來龍去脈更加清楚。
接下來的一部分是重構(gòu)已有腳本,創(chuàng)建一個(gè)用于檢查用戶是否有相應(yīng)權(quán)限的名為UserLogin的類。


class UserLogin {
var $_valid=true;
var $_id;
var $_name;
function UserLogin($name) { switch (strtolower($name)) { case ‘admin’:
$this->_id = 1;
$this->_name = ‘admin’;
break;
default:
trigger_error(“Bad user name ‘$name’”);
$this->_valid=false;
}
}
function name() {
if ($this->_valid) return $this->_name;
}
function Validate($user_name, $password) {
if (‘admin’ == strtolower($user_name)
&& ‘secret’ == $password) {
return true;
}
return false;
}
}
(在一個(gè)實(shí)際的程序中,你應(yīng)當(dāng)按照如上所示的邏輯來查詢相應(yīng)的數(shù)據(jù)表,這種小而且編寫起來費(fèi)神的類體現(xiàn)了你將如何運(yùn)用ServerStub來組織代碼———ServerStub是一個(gè)小型的表達(dá)你想法的類,但它只是在一些限制環(huán)境下可用。)

最后一部分是創(chuàng)建響應(yīng)。為了最終在瀏覽器中顯示,我們必須處理那不斷增長的HTML內(nèi)容,如果必要的話我們也會(huì)討論HTTP重定向。(你也可以執(zhí)行其他的http頭的操作——這樣說是為了能構(gòu)隱藏它——在一個(gè)成熟的做法中,但這里使用的是一段更簡單的代碼,是為了使例子容易理解與關(guān)注。)


class Response {
var $_head=’’;
var $_body=’’;
function addHead($content) {
$this->_head .= $content;
}
function addBody($content) {
$this->_body .= $content;
}
function display() {
echo $this->fetch();
}
function fetch() {
return ‘<html>’
.’<head>’.$this->_head.’</head>’
.’<body>’.$this->_body.’</body>’
.’</html>’;
}
function redirect($url, $exit=true) {
header(‘Location: ‘.$url);
if ($exit) exit;
}
}

給出了這些模塊后,也是時(shí)候?qū)⑦@些新開發(fā)的、已測(cè)試的組件聚合到一個(gè)頁面中了。讓我們寫一個(gè)最終的類來協(xié)調(diào)這個(gè)頁面的所以行為,取個(gè)合適的名字PageDirector。類PageDirector具有一個(gè)很簡單的運(yùn)用程序接口:你在實(shí)例化后可以用調(diào)用它的run()方法。

分享:《PHP設(shè)計(jì)模式介紹》第四章 單件模式
幾乎所有面向?qū)ο蟮某绦蛑�,總有一兩個(gè)資源被創(chuàng)建出來,在程序應(yīng)用中持續(xù)被共享使用。例如,這樣的一個(gè)資源,在一個(gè)電子商務(wù)程序的數(shù)據(jù)庫連接中使用:這個(gè)連接在應(yīng)用程序啟動(dòng)時(shí)初始化,程序于是

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