亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

PHP三層結(jié)構(gòu)(下) PHP實現(xiàn)AOP

 更新時間:2010年07月04日 22:18:58   作者:  
讓我們把注意力集中到中間服務(wù)層上來。中間服務(wù)層代碼比較簡單,只是調(diào)用數(shù)據(jù)訪問層代碼將留言保存到數(shù)據(jù)庫。


不過先不要忙著高興,有個問題就在這個可擴展性里。當(dāng)新的需求被提出之后,我們可以再添加 ILWordExtension 實現(xiàn)類,這個的確正確。但是將這個新類注冊到getExtArray函數(shù)里,等于說還是要修改主業(yè)務(wù)邏輯代碼。能不能不修改呢?每次有新的需求變化還是要告知主業(yè)務(wù)邏輯,這樣終歸不太好。最理想的情況是新的擴展代碼加入系統(tǒng)之后,主業(yè)務(wù)邏輯代碼不用修改,因為主業(yè)務(wù)邏輯根本不知道有新擴展這回事!為此我們還需要優(yōu)化一下設(shè)計方案,如圖2所示:

(圖2),加入擴展家族類

對于調(diào)用擴展的主程序(也就是中間服務(wù)類LWordServiceCore),只讓它知道有ILWordExtension(擴展)這件事就可以了,它不需要知道還有CheckPowerExtension(檢查權(quán)限擴展)、CheckContentExtension(檢查內(nèi)容擴展)和AddScoreExtension(加分?jǐn)U展)這三個類。對這三個類的調(diào)用過程被移動到LWordExtensionFamily (擴展家族類)里去了。

LWordExtensionFamily其實就是一個能存放多個ILWordExtension接口實例的容器類,從圖2中可以看出這個容器類不僅僅是實現(xiàn)了ILWordExtension接口,而且還聚合多個ILWordExtension接口的實例,所以它很特殊!對于LWordServiceCore類,這個類只知道ILWordExtension接口,但并不知道這個接口存在三個實現(xiàn)類。恰好LWordExtensionFamily類就實現(xiàn)了ILWordExtension接口,這很好的符合了中間服務(wù)類的要求,并且這個擴展家族類知道ILWordExtension存在三個實現(xiàn)類,并會一一調(diào)用它們, LWordExtensionFamily代碼大概如代碼8所示:
復(fù)制代碼 代碼如下:

// 代碼 8, 擴展家族
// 擴展家族
class LWordExtensionFamily implements ILWordExtension {
// 擴展數(shù)組
private $_extensionArray = array();
// 添加擴展
public function addExtension(ILWordExtension $extension) {
$this->_extensionArray []= $extension;
}
// 添加留言前
public function beforeAppend($newLWord) {
foreach ($this->_extensionArray as $extension) {
$extension->beforeAppend($newLWord);
}
}
// 添加留言后
public function behindAppend($newLWord) {
foreach ($this->_extensionArray as $extension) {
$extension->behindAppend($newLWord);
}
}
}

通過代碼8不難看出LWordExtensionFamily類雖然也實現(xiàn)了ILWordExtension接口,但是它并不做任何實質(zhì)的操作,而是通過循環(huán)語句將調(diào)用過程一一傳遞下去。為了平滑實現(xiàn)擴展到插入的方式,所以最好創(chuàng)建一個工廠類MyExtensionFactory。如代碼9所示:
復(fù)制代碼 代碼如下:

// 代碼 9
// 自定義擴展工廠
class MyExtensionFactory {
// 創(chuàng)建留言擴展
public static function createLWordExtension() {
$lwef = new LWordExtensionFamily();
// 添加擴展
$lwef->addExtension(new CheckPowerExtension());
$lwef->addExtension(new CheckContentExtension());
$lwef->addExtension(new AddScoreExtension());
return $lwef;
     // 注意這里返回的是擴展家族類對象,
     // 擴展家族 LWordExtensionFamily 恰好也實現(xiàn)了接口 ILWordExtension,
     // 所以這是符合業(yè)務(wù)邏輯的要求.
     // 從此, 業(yè)務(wù)邏輯可以不關(guān)心具體的擴展對象, 只要知道擴展家族即可
}
}

使用擴展工廠類的好處就是可以隨意的添加和移除擴展實例,這就很好的實現(xiàn)了可插入式編程。對于LWordServiceCore類只知道一個ILWordExtension接口,對于LWordExtensionFamily知道需要一一調(diào)用每個擴展,但是具體會有多少個擴展是通過MyExtensionFactory給出的。各負(fù)其責(zé)結(jié)構(gòu)也很清晰。如果我們做一個假設(shè),MyExtensionFactory類的createLWordExtension函數(shù)不是通過new關(guān)鍵字這樣的硬編碼方式來添加擴展列表,而是通過更巧妙的讀取配置文件的方式來得到擴展列表,那么是不是更方便更靈活呢?不過這個就不再本文中討論了。

中間服務(wù)層通過工廠類取得一個ILWordExtension接口的具體實例,然后調(diào)用其beforeAppend和behindAppend方法。當(dāng)然中間服務(wù)并不知道工廠類返回的其實是一個含有多個ILWordExtension實例的容器(因為這個容器也實現(xiàn)了ILWordExtension接口),所以中間服務(wù)也就不知道擴展是被一一調(diào)用的。完整代碼如代碼10所示:
復(fù)制代碼 代碼如下:

// 代碼 10, 完整代碼
// 擴展接口
interface ILWordExtension {
// 添加留言前
public function beforeAppend($newLWord);
// 添加留言后
public function behindAppend($newLWord);
};
// 檢查權(quán)限
class CheckPowerExtension implements ILWordExtension {
// 添加留言前
public function beforeAppend($newLWord) {
// 在這里判斷用戶權(quán)限
}
// 添加留言后
public function behindAppend($newLWord) {
}
};
// 檢查留言文本
class CheckContentExtension implements ILWordExtension {
// 添加留言前
public function beforeAppend($newLWord) {
if (stristr($newLWord, "fuck"))
throw new Exception();
}
// 添加留言后
public function behindAppend($newLWord) {
}
};
// 用戶積分
class AddScoreExtension implements ILWordExtension {
// 添加留言前
public function beforeAppend($newLWord) {
}
// 添加留言后
public function behindAppend($newLWord) {
// 在這里給用戶積分
}
};
// 擴展家族
class LWordExtensionFamily implements ILWordExtension {
// 擴展數(shù)組
private $_extensionArray = array();
// 添加擴展
public function addExtension(ILWordExtension $extension) {
$this->_extensionArray []= $extension;
}
// 添加留言前
public function beforeAppend($newLWord) {
foreach ($this->_extensionArray as $extension) {
$extension->beforeAppend($newLWord);
}
}
// 添加留言后
public function behindAppend($newLWord) {
foreach ($this->_extensionArray as $extension) {
$extension->behindAppend($newLWord);
}
}
}
// 自定義擴展工廠
class MyExtensionFactory {
// 創(chuàng)建留言擴展
public static function createLWordExtension() {
$lwef = new LWordExtensionFamily();
// 添加擴展
$lwef->addExtension(new CheckPowerExtension());
$lwef->addExtension(new CheckLWordExtension());
$lwef->addExtension(new AddScoreExtension());
return $lwef;
}
}
// 中間服務(wù)層
class LWordServiceCore implements ILWordService {
// 添加留言
public function append($newLWord) {
// 獲取擴展
$ext = MyExtensionFactory::createLWordExtension();
$ext->beforeAppend($newLWord);
// 調(diào)用數(shù)據(jù)訪問層
$dbTask = new LWordDBTask();
$dbTask->append($newLWord);
$ext->behindAppend($newLWord);
}
};

從代碼10中可以看出雖然CheckPowerExtension、CheckContentExtension、AddScoreExtension以及LWordExtensionFamily都實現(xiàn)了ILWordExtension接口,但是它們的beforeAppend和behindAppend函數(shù)過程卻完全不同!特別是LWordExtensionFamily擴展家族類,它并沒有實質(zhì)的業(yè)務(wù)邏輯處理過程,而是將調(diào)用依次傳遞給每一個擴展。beforeAppend和behindAppend函數(shù)在具體類中的不同實現(xiàn),這是面向?qū)ο蟪绦蛟O(shè)計中的很典型的特性:多態(tài)!
將次業(yè)務(wù)邏輯分散到各個擴展中,這種做法已經(jīng)非常近似AOP(Aspect OrientedProgramming,面向切面編程)的編程方式。權(quán)限校驗、內(nèi)容檢查和積分可以看作是不同的切面,這些切面和主業(yè)務(wù)邏輯交叉在一起,但又不會影響到主業(yè)務(wù)邏……這樣做的好處就是擴展代碼不會干擾主業(yè)務(wù)邏輯,我們也可以針對某一個擴展進行編碼和單元測試,然后通過MyExtensionFactory工廠類把擴展插入到業(yè)務(wù)流程中。完整的執(zhí)行過程如圖3所示:

(圖3),執(zhí)行流程


本文源碼下載地址:http://xiazai.jb51.net/201007/yuanma/TraceLWord.rar

相關(guān)文章

最新評論