<b>復雜要人命。它消磨開發者的生命,讓產品難以規劃、構建和測試。——Ray Ozzie</b>
1.如何建造一個城市
城市的建造沒辦法由一個人事無巨細得完成。需要分成全局部分和細節部分,讓相應的人去做好相應的模塊。
2.將系統的構造和使用分開
<b>構造</b>和<b>使用</b>是非常不一樣的過程。就像構造的工人和住在房子里的主人,對一棟房子的看法是完全不同的。
軟件系統應該講起始過程和運行過程的邏輯分開,在起始過程創造應用對象,也會存在互相纏結的依賴關系。
public ObjectA getObjectA(){
if(objectA!=null)
objectA = new ObjectA(……);
return objectA;
}
上面的就是所謂的延遲初始化/賦值。你永遠不會得到null的對象,且無心操心構造。但是這也導致了對象存在極其嚴重的硬編碼依賴。如果上述對象是個重型對象,則測試是個問題。我們必須保證在單元測試調用該方法以前指派恰當的測試替身或仿制對象。這往往會意味著邏輯的添加,從而造成了過重的權責,這顯然違反了<b>單一權責原則。</b>
顯然,如果類似的全局設置策略會在應用程序中四散分布,缺乏模塊組織性。
2.1分解main
將構造和使用分開的方法之一是將全部的構造過程搬遷到main或者被稱為main的模塊中。main穿件所有對象,傳遞給應用,而應用則僅僅是使用對象。
2.2工廠
應用程序不可能完全沒有創建對象的能力,因此這里提供了對象工廠,隔絕構造細節,卻有強大的對象構造能力。
2.3依賴注入
DI(Dependency Injection)是一種可以實現分離構造和使用的機制,是控制反轉在依賴管理中國的一種手段。在依賴管理中,對象不應該負責實體化對自身的依賴。反之應該將之交給其他有權力的機制,從而實現控制反轉。用DI容器實體化需要的對象,用構造器參數或者是賦值的方式將依賴連接到一起。
3.擴容
任何系統一開始就是開發完美,這是一個神話故事。我們應該將我們的目標集中于只做今天的用戶故事,然后重構,明天再擴展系統,完成新的故事。這里提到了AOP(面向切面編程)的概念,AOP是一種恢復橫貫式關注面模塊化的普適手段,
4.Java代理
Java代理適用于簡單的情況,例如在單獨的對象或者類中包裝方法調用。然而JDK提供的動態代理僅僅能夠與接口協同工作。代碼量和復雜度是代理的兩大弱點沒創建整潔的代碼很難。
5.其他
Spring有純面向切面編程的框架,AspectJ則是更具有表現力的工具。
應該測試驅動系統架構,沒必要BDUF(Big Design Up Front)。
最佳的系統架構由模塊化的關注面領域組成,每個關注面均用純Java對象實現。不同的領域之間用最不具有侵害性的方面或類方面工具整合起來。這種架構能測試驅動。
擁有模塊化的POJO系統提供敏捷能力,允許我們基于最新的知識修改。
系統要用領域特定語言(DSL)。