1. 程式人生 > >設計中的控制反轉(Inverse of Control)

設計中的控制反轉(Inverse of Control)

WTF IOC?

java面試中經常會碰到如下情景:

問:“你用過Spring嗎?”

答:“用過” 

問:"Spring有啥特點“?

答:”IOC和AOP" 

問:"AOP是啥?怎麼實現AOP"?

答:"AOP就是面向切面程式設計,將像log, transaction, statistical這種本來分散在各個邏輯模組中的輔助程式碼抽象成單獨的模組;然後將其注入(植入)到業務邏輯的程式碼中。(參考什麼是AOP)。實現有動態代理,修改class位元組碼等

問:“什麼是動態代理”

答:”......" 

關於Spring中的IOC,談到的較少。

IOC是控制反轉,反轉啥?在layer結構中,通常是上層呼叫下層的介面,上層依賴於下層,即呼叫者依賴於被呼叫者。而控制反轉的意思就是使得上層不依賴於下層的介面,呼叫者來決定被呼叫者。

實現原則:

  • 上層模組不依賴於下層模組,而是依賴於抽象介面;且該抽象介面而上層模組來定義
  • 抽象層不依賴於具體的實現,具體的實現依賴於抽象;即下層模組來實現上層模組定義的介面
這樣,上層模組可以採用一定的機制來選擇不同的下層實現,完成控制反轉。 wiki總結有6種依賴注入的機制
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)

===========================================================================

在定義好User case後,我們快速開發系統的原型(Prototype Demo); 

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.