關于IoC的的概念提出來已經很多年了,其被用于一種面象對像的設計。我在這里再簡單的回顧一下這個概念。我先談技術,再說管理。
話說,我們有一個開關要控制一個燈的開和關這兩個動作,最常見也是最沒有技術含量的實現會是這個樣子:
然后,有一天,我們發現需要對燈泡擴展一下,于是我們做了個抽象類:
但是,如果有一天,我們發現這個開關可能還要控制別的不單單是燈泡的東西,我們就發現這個開關耦合了燈泡這種類別,非常不利于我們的擴展,于是反轉控制出現了。
就像現實世界一樣,造開關的工廠根本不關心要控制的東西是什么,它只做一個開關應該做好的事,就是把電接通,把電斷開(不管是手動的,還是聲控的,還是光控,還是遙控的),而我們的造各種各樣的燈泡(不管是日關燈,白熾燈)的工廠也不關心你用什么樣的開關,反正我只管把燈的電源接口給做出來,然后,開關廠和電燈廠依賴于一個標準的通電和斷電的接口。于是產生了IoC控制反轉,如下圖:
所謂控制反轉的意思是,開關從以前的設備的專用開關,轉變到了控制電源的開關,而以前的設備要反過來依賴于開關廠聲明的電源連接接口。只要符合開關廠定義的電源連接的接口,這個開關可以控制所有符合這個電源連接接口的設備。也就是說,開關從依賴設備這種情況,變成了,設備反過來依賴于開關所定義的接口。
只要你看過我的那篇《面向對象設計其實和面象對象一點關系也沒有》,你就知道這樣的例子在生活中太多見了。比如說:
1)在交易的過程中,賣家向買家賣東西,一手交錢一手交貨,所以,基本上來說賣家和買家必需強耦合(必需見面)。這個時候,銀行出來做擔保,買家把錢先墊到銀行,銀行讓賣家發貨,買家驗貨后,銀行再把錢打給賣家。這就是反轉控制。買賣雙方把對對方的直接控制,反轉到了讓對方來依賴一個標準的交易模型的接口。股票交易也是一樣的,證交所就是買賣雙方的標準交易模型接口。
2)上面這個例子,可能還不明顯,再舉一個例子。海爾公司作為一個電器制商需要把自己的商品分銷到全國各地,但是發現,不同的分銷渠道有不同的玩法,于是派出了各種銷售代表玩不同的玩法,隨著渠道越來越多,發現,每增加一個渠道就要新增一批人和一個新的流程,嚴重耦合并依賴各渠道商的玩法。實在受不了了,于是制定業務標準,開發分銷信息化系統,只有符合這個標準的渠道商才能成為海爾的分銷商。讓各個渠道商反過來依賴自己標準。反轉了控制,倒置了依賴。
可見,控制反轉和依賴倒置不單單的一種設計模式,反而更是一種管理模式。
在大公司中,有很多很多的團隊,這些團隊開發的軟件有很多依賴,跨團隊合作是一件挺麻煩的事情,下面是一些比較真實的示例:
1)一個網頁會有很多頻道,于是,我們的前端工程師進入到各個頁面為各種頻道開發他們的頁面,隨著頻道越來越多,前端開發工程師的人數也越來越多,每增加一個頻道,就要增加一個為這個頻道服務的前端團隊,于是,人數越來越多,干成了勞動密集型。為什么不反轉控制,倒置依賴呢?前端的同學完全可以開發出各種頁面的標準組件,布局,模板,以前與后端交互框架,然后,讓后端的同學反過來依賴于前端的標準,使用前端的框架,前端的布局,模板,和組件,以向前端接入后端的模塊。
2)一個平臺需要接入各種各樣的業務系統,這些垂直業務系統都有自己的賬號體系,于是這個平臺為了要兼這些垂直系統的賬號體系以做到權限控制,需要做各個系統和自己系統中的賬號映射,并為賬號和分配出來的資源設置各垂直系統的標識,還要在自己的代碼中要寫很多很多的依賴于各種賬號體系的代碼。其實,一個依賴倒置和反轉控制就很簡單。開發一個權限體系標準,讓接入方的賬號系統反過來依賴并控制這個標準的權限系統,從而做出一個干凈的系統。
3)還有一個云平臺中的管理模式,一些底層服務的開發團隊只管開發底層的技術,然后什么也不管了,就交給上層的開發人員,在底層團隊的開發出來的產品上面開發各種管理這個底層資源的東西,比如:生產底層資源的業務,底層資源的控制臺,底層資源的監控系統。這個讓底層團隊只干純技術,不干與底層技術無關的東西,看似很科學,其實是做錯了。因為,上層為各個云資源控制生產,開發控制臺和監控的團隊,隨著接入的資源的越來越多,完全干不過來了,苦逼得一塌糊涂,因為底層的資源千差百怪,每接一個就要開發一堆這個產品的代碼。這個時候依賴倒置和反轉控制又可以解決問題了。很簡單,上層為各個云資源控制生產,開發控制臺,和監控的團隊應該制定一個標準,讓底層的IaaS云資源開發團隊反過來依賴這個標準,統一接入方式,如果開發的云資源不符我的生產控制模型,沒有控制臺,不把監控數據喂入我的監控系統,對不起,請不要接入我這個PaaS平臺。
4)一個集中式的處理電子商務中的訂單的流程。各個垂直業務線都需要通過這個平臺來處理自己的交易業務,但是垂直業務線上的個性化需求太多。于是,這個技術平臺開始出現了黑魔法——“為了害怕改變數據庫表結構,不得不在數據庫中預留一些字段,里面存把業務方的個性化字段存成如JSON這樣的東西”,并為之自豪認為可以快速解決業務問題(WTF)。然而,惡夢并沒就此結束,管理這個技術平臺的小組開始發現,對來自各個業務方的需求應接不暇,各種變態需求嚴重干擾系統,各種技術決定越來越不好做,導致需求排期排不過來。于是,不單單得到了各個業務方的各種抱怨,最可怕的是還有高層老大們壓過來的Deadline,加班加點,苦逼之極,最后業務方自己要去一個自己的平臺。為什么不用依賴倒置和反轉控制的思想呢?開發一個插件模型、工作流引擎和Pub/Sub系統,讓業務方的個性化需求可以以插件的方式插入我的訂單流程中,業務方自的數據存在自己的庫中,業務邏輯也不要侵入我的系統,并可以使用工作流引擎或Pub/Sub的協義標準來自己定義工作流的各個步驟(甚至把工作流引擎的各個步驟的Decider交給各個業務方自行處理)。讓各個業務方來依賴于我的標準插件和工作流接口,反轉迭控制,讓他們來控制我的系統,依賴倒置,讓他們來依賴我的標準。(這個團隊想過把自己的系統內部開源出去讓別的團隊也進來參與,可以是可以,但一定要用Linux/Git這種方式,允許出現多個分支,多個發行版。但多個版本又造成了多個業務平臺,這會上上層垂直業務不知所措)
5)看過《SteveY對Amazon和Google平臺的吐槽》的人都知道,Amazon內部系統的SOA架構(這個SOA架構離IBM定義的那個非常變態的SOA還有一定距離),但是這基本上都是依賴倒置和控制反轉的思路了—— 與其讓我來幫你實現你的業務邏輯,不如把我的業務邏輯開放成服務的方式讓你來控制。
6)再說一個我在Amazon經歷的例子。有一個項目是在給Amazon的各個商區(Marketplace)做國際出口的業務,我們先把Media類的產品(書,DVD之類的)做國際出口開放,項目不難,就是讓商家同意一個法律協議(上傳自己的簽名),然后后臺小改一下。美國的,歐洲的做的都沒有問題,物流團隊在出口報關單上打的都是Amazon倉庫的地址和商家的簽名(本來這就是錯的,打的應該是商家的地址和商家的簽名),但是到了日本,就出了問題,因為日本海關即要日文信息,也要商家的英文名和英文地址,而我們的系統里面只有商家的日文信息。本來,這是一個挺簡單的事——數據庫里加兩個字段,在那個同意條款的網頁上收集一下商家的英文名和地址,然后把這些信息傳給后面的物流團隊。物流團隊一看這個,發現搞不了,因為他還要傳給倉庫,N多的地方都要加這兩個字段,還要寫下各種if (site == JP)這樣的判斷。物流團隊不蠻干,重新設計自己的系統。做一個Document Template的東西,這個就是那個那個要貼在物流盒子上的單子。再也不讓各個業務團隊把那些信息傳過來,而是把這個Document Template的東西傳給上面的業務方,他們想怎么寫就怎么寫, 寫完后,把這個東西傳回來。于是,大家依賴了一個標準的協議,而不是一其字段。(當然,這個改動過多,為此改了半年多,不過非常值)
所以說啊,在跨團隊的工作中,
-
如果依賴和控制的東西過多了,就需要制定標準,倒置依賴,反轉控制。
-
控制欲望最好不要太強,不要想著能干所有的事情,要學會控制反轉和依賴倒置原則。否則只會引火燒身。
-
反轉控制和依賴倒置是一種智慧。
轉自:http://coolshell.cn/articles/9949.html
原創文章,作者:s19930811,如若轉載,請注明出處:http://www.www58058.com/2135