在開始前必須先坦承,這篇的內容充滿許多我並不清楚的專有名詞,且大概是因為作者認為都是些基礎知識,是以也沒有另外說明及補充。因此,今天我能吸收跟分享的東西並不多,篇幅也會短些。
起始過程是每個應用程式都必須關注的事。......將所有關注的事分離開來,是在軟體技巧中,最古老、最重要的設計技巧之一。
建造與使用,是非常不同的過程,就如同一棟建築在剛開始打地基、建樓層時所用的器具及所具備的外觀,都與建造完成後大不相同。程式也是如此,建造與使用應該分別對待。
public Service getService() {
if(service == null )
service = new MyServiceImpl(...);
return service
}
上述是一個典型的例子,包含延遲初始 / 延遲賦值 (LAZY INITIALIZATION / EVALUATION)。
這是程式中慣用的手法,具備許多方便性與優點,然而,它同時也帶來許多問題。
首先,該函式與 MyServiceImpl 產生高度耦合,我們在呼叫它的時候,被迫去了解 MyServiceImpl 中建構子的細節,並且其內容是硬編碼 (hard code)。
其次,我們難以對它進行測試。若 MyServiceImpl 是龐大的物件,則我們須確保在呼叫該方法前,就已妥善指派適當的 mock 。更嚴重的是,我們無法得知 MyServiceImpl 物件是否在所有狀態下都是正確的物件。
因此,若我們希望打造一個耐用的程式,就不該破壞程式的模組性,反而應使不同的邏輯彼此分離,來解決相依性問題。
在 OOP 程式設計領域,「SOLID」是極重要且廣為人知的原則。其中的「D」,指的是依賴反轉(Dependency inversion principle, DIP),該原則能夠幫助系統的關注點分離,使程式中高層次的概念不會相依於低層次的細節,進而解耦。至於該原則的細節,由於各處資料非常充足且不是書中重點,這裡就不詳述。
就像一個城鎮會隨著當下的狀態與需求而漸漸改變,我們很難看到一個小村落在初始就擁有六線道的寬廣馬路,必然是在交通有疏散壓力時,才會逐漸拓寬道路。同樣,程式中的系統也同樣很難一次到位,定是隨著功能需求才漸漸演變成形,而保持關注點分離,保持系統架構的解耦,才能讓程式具備擴大、成長的彈性。
至於一個難以改變的程式,就如我們第八天開頭所說的,那該是硬體而非軟體了。