通過之前的七個章節(jié),我們已經(jīng)創(chuàng)建了一個以博客作為示例的完整功能的增刪改查應(yīng)用程序。在我們制作的過程中應(yīng)用了幾種不同的設(shè)計模式和最佳實(shí)踐。現(xiàn)在是時候來重新數(shù)一數(shù)并且看看其中一些我們寫過的代碼示例了。這將會以問與答的形式呈現(xiàn)。
簡單回答:不是。
詳細(xì)回答:接口的重要性會隨著你的應(yīng)用程序的增長而增長。如果你可以預(yù)見到你的應(yīng)用程序會被其他人使用并且是可擴(kuò)展的,那么你應(yīng)該好好地考慮一下編碼時總是使用接口。這是非常常見的最佳實(shí)踐,而且和 ZF2 沒有直接關(guān)系,更多的是遵守嚴(yán)格的面向?qū)ο蟪绦蚓幊桃?guī)范。
我們介紹過的多層架構(gòu)(控制器 -> 服務(wù) -> 映射器 -> 后端)的用處在于讓我們嚴(yán)格地分開考慮所有的對象。有許多可用的資源可以為您詳細(xì)解釋每一個分層的巨大優(yōu)勢,所以請自行參閱。
然而,對于十分簡單的應(yīng)用程序,你很可能會將映射器層刪減掉。實(shí)際上所有映射器的代碼層通常都直接存放在服務(wù)內(nèi)部。而且這招對大多數(shù)應(yīng)用程序都好使,但一旦你開始打算支持多個后端(例如開源軟件);又或者,你想準(zhǔn)備好更換后端,那么你應(yīng)該總是考慮是否要包含這一層。
簡單回答:沒錯。
詳細(xì)回答:實(shí)際上沒必要詳細(xì)回答。大多數(shù)代碼重疊也都來自于映射器層、如果你自己看看那些類,你就會注意到實(shí)際上只有兩件事情是和某個具體對象捆綁的。第一件就是,數(shù)據(jù)庫表的名稱;第二件就是,事實(shí)上是對象原型會被傳值給映射器。
原型已經(jīng)從 __construct()
函數(shù)傳進(jìn)類里所以它已經(jīng)是可替換的。如果你想讓表名也是可替換的話,你只需要在構(gòu)造器中提供表名即可,然后你就有了一個全能的數(shù)據(jù)庫映射器實(shí)現(xiàn),基本上可以用來處理你的應(yīng)用程序里幾乎所有的對象。
你可以參照下例來編寫一個 factory 類:
<?php
class NewsMapperFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
return new ZendDbSqlMapper(
$serviceLocator->get('Zend\Db\Adapter\Adapter'), // 數(shù)據(jù)庫適配器
'news', // 表名
new ClassMethods(false), // 對象充水器
new News() // 對象原型
);
}
}
如果你回過頭去看幾年前的代碼示例,就會發(fā)現(xiàn)曾經(jīng)在每個控制器里面都有大量的代碼。這已經(jīng)被認(rèn)為是一個不良實(shí)踐,這類控制器被稱為“肥胖控制器”或者“臃腫控制器”。
我們之前創(chuàng)建的每個控制器之間的主要區(qū)別是不同的控制器有不同的依賴對象。舉例來說,WriteController
要求 PostForm
和 PostService
,然而 DeleteController
只要求 PostService
。對于這個例子來說,將 deleteAction()
寫入 WriteController
是不合理的,因?yàn)檫@會導(dǎo)致過程中創(chuàng)建一個不必要的 PostForm
實(shí)例。在大型程序中這種錯誤會制造巨大的性能瓶頸,從而拖慢應(yīng)用程序。
再看看 DeleteController
和 ListController
,你會注意到兩個控制器都有一樣的依賴對象。兩者都只要求 PostService
,那么為何不將其合并成一個控制器呢?原因是語義,你會跑去 ListController
尋找 deleteAction()
嗎?我們大多數(shù)人不會干這事,所以我們?yōu)槠浣⒘艘粋€新類。
在應(yīng)用程序中的 InsertForm
和 UpdateForm
互有區(qū)別,你也許會總是想將其分為兩個控制器而不是像我們的例子中將其做成一個聯(lián)合的 WriteController
。這類事情基本上是因應(yīng)用程序的不同而不同,不過基本目標(biāo)一直都是:讓你的控制器總是纖細(xì)/輕量。
如果你覺得這個 FAQ 還少了點(diǎn)什么,請將你的問題私信給我們,然后我們會給你答案!
更多建議: