設計中的控制反轉(Inverse of Control)
WTF IOC?
java面試中經常會碰到如下情景:
問:“你用過Spring嗎?”
答:“用過”
問:"Spring有啥特點“?
答:”IOC和AOP"
問:"AOP是啥?怎麼實現AOP"?
答:"AOP就是面向切面程式設計,將像log, transaction, statistical這種本來分散在各個邏輯模組中的輔助程式碼抽象成單獨的模組;然後將其注入(植入)到業務邏輯的程式碼中。(參考什麼是AOP)。實現有動態代理,修改class位元組碼等
問:“什麼是動態代理”
答:”......"
關於Spring中的IOC,談到的較少。
IOC是控制反轉,反轉啥?在layer結構中,通常是上層呼叫下層的介面,上層依賴於下層,即呼叫者依賴於被呼叫者。而控制反轉的意思就是使得上層不依賴於下層的介面,呼叫者來決定被呼叫者。
實現原則:
- 上層模組不依賴於下層模組,而是依賴於抽象介面;且該抽象介面而上層模組來定義
- 抽象層不依賴於具體的實現,具體的實現依賴於抽象;即下層模組來實現上層模組定義的介面
factory pattern | |
service locator pattern | |
建構函式注入 |
Spring |
setter注入 | Spring |
上下文查詢 | JINI ? |
設計中的控制反轉
在三層結構中,我們一般的設計順序是
===========================================================================
User Case
|
DB Schema (Data layer)
|
Service Interface (Logic layer)
|
JSP/Javascript (Presentation Layer)
===========================================================================
根據上面的設計順序,Service Interface 依賴於DB Schema,而JSP/Javascript 依賴於Service Interface,上層依賴於下層。
一種常見的說法是:service的介面定義並不依賴於DB層,但是:
1) service的實現直接依賴於Data層的DAO interface
2) DB schema設計的好壞直接影響著service的實現,間接的影響著service的介面
往上推之,Presentation Layer同樣依賴於Service Interface.
採用控制反轉的思路,系統設計順序如下:
===========================================================================
User Case
|
JSP/Javascript (Presentation Layer)
|
Frontend API Contract (Contract Layer)
|
Service Interface (Logic layer)
|
DB Schema (Data layer)
===========================================================================
Prototype完畢,根據User case和Presentation Layer的code定義出前端API Contract, 所有jsp/javascript使用此介面。
後端邏輯層實現前端的Frontend contract API,控制反轉,讓後端依賴於前端。
兩種設計順序的區別在哪?
前者是以DB Schema作為穩定的data model,後者是以API(class)作為穩定的data model.
軟體開發中有句話:
Requirements Are Like Water. They're Easier To Build On When They're Frozen
API(class)相比DB schema,更能直接的反映Frozen的requirements.
Contract API 和 Service API 的區別在哪?
Contract API 更加面向前端(web/web service),面向user case,一般是粗粒度的介面;
Service API 則更加面向實現,是較細粒度的介面;
適用場景
如果你有一套遺留系統,修修補補都相當費事--太多的technique debt.
現在打算開發一套新的系統,已有系統的元件/service又不想全部扔掉,畢竟有些元件還是相當有用。
於是你想和遺留系統的一部分元件進行對接。
一方面是新的系統/UI,一方面又是老的介面/模型。直接對接嗎?
引入一層Adapter layer,定義新系統的contract api, 新系統前端在此API上進行開發。
後臺是繼續和遺留系統對接,還是徹底推翻,重新來過,all is hidden to upper layer.