作者 | 李志信(冀鋒)來源 | 阿里開發(fā)者公眾號
IOC(inversion of control)即控制反轉(zhuǎn),是面向對象編程中的一種設(shè)計原則,可以用來減低計算機代碼之間的耦合度。IOC-golang 是一款服務(wù)于Go語言開發(fā)者的依賴注入框架,基于控制反轉(zhuǎn)思路,方便開發(fā)人員搭建任何 Go 應(yīng)用。
在本文中,我不會羅列這個項目的種種功能與實現(xiàn),而是站在開發(fā)者的角度,談一談我認為 Go 應(yīng)用開發(fā)的“理想姿態(tài)”。
項目背景
在面向?qū)ο缶幊痰乃悸废拢_發(fā)者需要直接關(guān)心對象之間的依賴關(guān)系、對象的加載模型、對象的生命周期等等問題。對于較為復(fù)雜的業(yè)務(wù)應(yīng)用系統(tǒng),隨著對象數(shù)目增長,對象之間的拓撲關(guān)系呈指數(shù)級增加,如果這些邏輯全部由開發(fā)人員手動設(shè)計和維護,將會在應(yīng)用內(nèi)保存較多業(yè)務(wù)無關(guān)的冗余代碼,影響開發(fā)效率,提高代碼學(xué)習成本,增加了模塊之間的耦合度,容易產(chǎn)生循環(huán)依賴等等問題。
隨著開發(fā)者的增多,設(shè)計模型的復(fù)雜化,將會產(chǎn)生對象管理框架的訴求,例如 Java 生態(tài)的 Spring 框架,其設(shè)計的核心就是控制反轉(zhuǎn)思路,從而為開發(fā)者提供依賴注入、配置注入、生命周期管理等能力。Go 語言生態(tài)在開源側(cè)也有較多基于該思路的實現(xiàn),但普遍能力較為單一,相比于我們的設(shè)計思路 ,在可擴展性、易用性等方面有所不足。
IOC-golang 不是 Go 語言實現(xiàn)的 Spring 框架!
我們致力于打造一款針對 Go 開發(fā)人員的框架,它適配與 Go 的語法和各種基本概念,符合 Go 語言開發(fā)習慣,能真正為開發(fā)人員提供編程、思考、運維、以及代碼閱讀上的便利。
設(shè)計思路
讓我們聊一些輕松的話題。
應(yīng)用開發(fā)思路
應(yīng)用程序多種多樣,都是由開發(fā)人員一行一行代碼編寫出來的,身為開發(fā)人員,在編寫代碼之前,一定是對接下來要寫的每一行代碼有初步的思考與設(shè)計。例如,我身為一個 Go 開發(fā)人員,如果期望編寫一個web 后端服務(wù)程序,那么我會怎么做?
最直觀的思路,我需要啟動一個http server,用于監(jiān)聽某個端口,并且處理http協(xié)議的請求。使用面向?qū)ο蟮乃悸罚倚枰獦?gòu)建一個http server對象,之后調(diào)用方法開啟監(jiān)聽。再往下一層思考,這個http server 對象如果要創(chuàng)建出來,需要依賴一些對象,這些對象可能包含:多個 http handler 對象、用于可視化上報的對象、管理安全認證的對象等等。再下一層,一個http handler 對象依賴的對象有:負責執(zhí)行序列化操作的對象、傳輸結(jié)構(gòu)對象、業(yè)務(wù)處理對象;業(yè)務(wù)處理對象又依賴一些sdk,例如緩存客戶端對象、數(shù)據(jù)庫客戶端對象等等。我們現(xiàn)在層層思考的過程,也就是自頂向下的設(shè)計模型。
我們可以把一個復(fù)雜的應(yīng)用程序,根據(jù)依賴關(guān)系,抽象為一個具有單起點的有向圖,以上面描述的場景為例,我們可以畫出具有如下拓撲的圖。
腦海中有了這些拓撲,就可以按照習慣的方式編寫代碼了,我可能選擇先把未實現(xiàn)的模塊抽象成接口,由上至下編寫結(jié)構(gòu),我也可能習慣自底向上開發(fā),先從最具體的底層結(jié)構(gòu)入手,然后用多個子結(jié)構(gòu)組成一個完整的上層結(jié)構(gòu)。無論選擇哪種實現(xiàn)方案,我在開發(fā)時總會關(guān)心一件事情:我要開發(fā)的結(jié)構(gòu),是由哪些結(jié)構(gòu)組成的,我把這個事情稱作一個“開發(fā)單元”,這也是IOC-golang 框架關(guān)心的主要問題之一。
按照常規(guī)的應(yīng)用開發(fā)模式,在一個“開發(fā)單元”內(nèi),開發(fā)者需要關(guān)注哪些事情?我們習慣于編寫一個構(gòu)造函數(shù)返回需要的對象,這個構(gòu)造函數(shù)的入?yún)ⅲ艘恍﹨?shù)以及下游依賴,我們在構(gòu)造函數(shù)中會把這些對象和參數(shù)拼接成一個結(jié)構(gòu),再執(zhí)行初始化邏輯,最后返回。
我們把這個“開發(fā)單元”關(guān)心的東西,按照依賴關(guān)系抽象成下圖。
也就是說,如果想基于一個結(jié)構(gòu)構(gòu)造出一個對象,我們最多需要提供這三個東西就夠了:參數(shù)/配置、依賴的子對象和一段包含初始化邏輯的函數(shù),當然對于一些簡單的結(jié)構(gòu),可能只需要三者中的一兩者,甚至都不需要。按照這一思路,開發(fā)人員可以把 “編寫一個應(yīng)用” ,拆分成若干個 “構(gòu)造一個對象”的過程,二者是等價的,我們都在編碼的過程中,潛移默化地做了這件事情。
點擊鏈接查看原文,關(guān)注公眾號【阿里開發(fā)者】獲取更多福利!https://mp.weixin.qq.com/s/Ar-JdkrQ5NnCWcGOoCuVgg