|
復(fù)制代碼 代碼如下:
// 代碼 1
// 外觀層類
class LWordHomePage {
// 添加留言
public function append($newLWord) {
// 調(diào)用中間服務(wù)層
$serv = new LWordServiceCore();
$serv->append($newLWord);
}
};
// 中間服務(wù)層
class LWordServiceCore {
// 添加留言
public function append($newLWord) {
// 調(diào)用數(shù)據(jù)訪問(wèn)層
$dbTask = new LWordDBTask();
$dbTask->append($newLWord);
}
};
// 數(shù)據(jù)訪問(wèn)層
class LWordDBTask {
// 添加留言
public function append($newLWord) {
// 數(shù)據(jù)層代碼(省略)
}
};
執(zhí)行時(shí)序圖,如圖1所示:
(圖1),簡(jiǎn)單三層結(jié)構(gòu)時(shí)序圖
從代碼和時(shí)序圖中可以直觀看出三層結(jié)構(gòu)的調(diào)用順序。但實(shí)際開(kāi)發(fā)中這種簡(jiǎn)單三層結(jié)構(gòu)并不能滿足需求!我們先從外觀層與中間服務(wù)層這兩層的代碼開(kāi)始討論。在外觀層LWordHomePage類中直接使用new關(guān)鍵字創(chuàng)建并調(diào)用中間服務(wù)類LWordServiceCore屬于一種硬編碼的方式。在實(shí)際項(xiàng)目開(kāi)發(fā)過(guò)程中,外觀層和中間服務(wù)層可能會(huì)由不同的人員來(lái)開(kāi)發(fā),即一個(gè)功能模塊由多個(gè)人共同完成。而外觀層LWordHomePage類的開(kāi)發(fā)進(jìn)度是不可能等到LWordServiceCore類完全開(kāi)發(fā)完成之后才開(kāi)始(換句話來(lái)說(shuō)就是,外觀層不可能等到中間服務(wù)層完全開(kāi)發(fā)完成之后才開(kāi)始),這樣的協(xié)作效率非常低!為了使項(xiàng)目可以由多人同時(shí)開(kāi)發(fā),所以我們要切割代碼設(shè)計(jì)。我們可以組織一個(gè)臨時(shí)的中間服務(wù)類來(lái)滿足外觀層的開(kāi)發(fā)進(jìn)度。等到中間服務(wù)層完全開(kāi)發(fā)完成之后,替換一下就可以了……如圖2所示:
(圖2),外觀層在不同的服務(wù)間切換
顯然,要實(shí)現(xiàn)這樣的需求,在外觀層中直接使用new關(guān)鍵字創(chuàng)建和調(diào)用LWordServiceCore類是非常不靈活的!這很難做到靈活的隨意的切換??!我們可以創(chuàng)建TempService類充當(dāng)中間服務(wù)層的臨時(shí)實(shí)現(xiàn)。我們還需要分析一下TempService和LWordServiceCore這兩個(gè)類,它們都具備相同的append函數(shù)用于添加留言,只不過(guò)一個(gè)是臨時(shí)的而另外一個(gè)是真實(shí)的。既然TempService和LWordServiceCore這兩個(gè)類都有公共函數(shù),那么就應(yīng)該可以有一個(gè)公共的父類。考慮到對(duì)這個(gè)公共的上級(jí)類沒(méi)有別的成員和屬性,所以將這個(gè)公共的上級(jí)類定義為接口,即ILWordService!UML類圖如圖3所示:
(圖3)定義和實(shí)現(xiàn)ILWordService接口
在LWordHomePage類中并不直接創(chuàng)建TempService或者LWordServiceCore類對(duì)象,創(chuàng)建過(guò)程會(huì)交給一個(gè)工廠類MyServiceFactory(簡(jiǎn)單工廠模式)。這樣一來(lái),外觀層中的LWordHomePage類只需要知道ILWordService接口即可,外觀層代碼并不關(guān)心具體的中間服務(wù)代碼是什么,這樣就極好的實(shí)現(xiàn)了外觀層與具體服務(wù)代碼的分離。
這相當(dāng)于什么呢?就好比兩個(gè)硬件工程師,一個(gè)是制造計(jì)算機(jī)顯卡的,一個(gè)是制造計(jì)算機(jī)主板的。制造顯卡的工程師可以把顯卡插到到一塊測(cè)試電路中,來(lái)測(cè)試顯卡是否可以正常工作?同樣,制造主板的工程師也可以把主板插入到另一塊測(cè)試電路中,來(lái)測(cè)試主板是否可以正常工作?等到這兩位工程師都各自完成工作之后,將他倆的工作成果對(duì)接在一起就可以了。這是一種并行開(kāi)發(fā)方式,幾乎可以省掉一半的時(shí)間。從軟件工程的角度來(lái)講,我們?cè)谠O(shè)計(jì)接口代碼的時(shí)候也應(yīng)該考慮是否需要支持多人同時(shí)開(kāi)發(fā),從而提高生產(chǎn)效率。
依照UML類圖(如圖3所示),我們修改php代碼如代碼2所示:
復(fù)制代碼 代碼如下:
// 代碼2, 通過(guò)工廠創(chuàng)建留言服務(wù)并調(diào)用
// 外觀層類
class LWordHomePage {
// 添加留言
public function append($newLWord) {
// 調(diào)用中間服務(wù)
$serv = MyServiceFactory::create();
// 注意此時(shí)是操作 ILWordService 接口, 而非 LWordService 類
$serv->append($newLWord);
}
};
// 留言服務(wù)接口
interface ILWordService {
public function append($newLWord);
};
// 服務(wù)工廠類
class MyServiceFactory {
// 創(chuàng)建留言服務(wù)
public static function create() {
if (1) {
// 返回中間服務(wù)層
return new LWordServiceCore();
} else {
// 返回臨時(shí)實(shí)現(xiàn)
return new TempService();
}
}
}
// 臨時(shí)服務(wù)類
class TempService implements ILWordService {
// 添加留言
public function append($newLWord) {
// 臨時(shí)代碼(省略)
}
};
// 中間服務(wù)層
class LWordServiceCore implements ILWordService {
// 添加留言
public function append($newLWord) {
// 調(diào)用數(shù)據(jù)訪問(wèn)層
$dbTask = new LWordDBTask();
$dbTask->append($newLWord);
}
};
// 數(shù)據(jù)訪問(wèn)層
class LWordDBTask {
// 添加留言
public function append($newLWord) {
// 數(shù)據(jù)層代碼(省略)
}
};
時(shí)序圖如圖4所示:
(圖4)通過(guò)工廠類創(chuàng)建留言服務(wù)
php技術(shù):PHP三層結(jié)構(gòu)(上) 簡(jiǎn)單三層結(jié)構(gòu),轉(zhuǎn)載需保留來(lái)源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。