關(guān)于組件化系統(tǒng)如何實(shí)現(xiàn)的一點(diǎn)想法
組件化的業(yè)務(wù)系統(tǒng)架構(gòu)觀念據(jù)說已經(jīng)提出來20多年了,可是至今沒有見到讓人信服的組件化業(yè)務(wù)系統(tǒng)(注:組件化≠模塊化).關(guān)于業(yè)務(wù)組件是什么,長什么樣子,如何實(shí)現(xiàn),又有什么樣的遠(yuǎn)景? 大家也都做了很多思考和討論.
看了社區(qū)里的一些內(nèi)容,再加上平時跟同事們的交流和討論,對組件化業(yè)務(wù)系統(tǒng)的實(shí)現(xiàn)產(chǎn)生了一點(diǎn)想法。下面我說下我的想法,歡迎大家來拍磚討論。
我覺得目前大家對業(yè)務(wù)組件有一個共識:就是各個業(yè)務(wù)組件相對獨(dú)立,并且具有可組裝性和可插拔性。
每個組件的運(yùn)行僅依賴于平臺或者容器,組件與組件之間不存才直接的耦合關(guān)系。同時,組件與組件之間又并非絕對的獨(dú)立。組件經(jīng)過組裝后可以與其他的組件進(jìn)行業(yè)務(wù)上的交互。比如銷售組件與財(cái)務(wù)組件,一筆銷售業(yè)務(wù)的完成必定會產(chǎn)生一筆或幾筆財(cái)務(wù)的業(yè)務(wù),如銷售發(fā)票的開出和一筆新的應(yīng)收應(yīng)付或者現(xiàn)金銀行的記賬。又比如,采購與庫存管理,當(dāng)采購的需求被提出,那么是不是要先看看倉庫是不是有存貨呢?如果本倉庫沒有,是否允許從其他倉庫調(diào)撥呢?等等等等……,諸如此類的業(yè)務(wù)場景無法窮盡,而不同行業(yè)不同規(guī)模的用戶他們的業(yè)務(wù)過程又各自不同。
也就是說,組件之間的交互在業(yè)務(wù)上存在著不可規(guī)范和不可窮盡的特點(diǎn).這是個比較頭疼的問題,暫且記下,稍后再做討論。
另外,我的理解:組件化是介于模塊化與應(yīng)用系統(tǒng)集成之間的一個概念.關(guān)于組件化、模塊化、應(yīng)用的不同,社區(qū)中的一篇文章寫得很好。這篇文章的最后,提到了組件化不同于模塊化,引文:模塊化開發(fā)不同于組件開發(fā),模塊化開發(fā)只是在邏輯上做了切分,物理上(開發(fā)出的系統(tǒng)代碼)通常并沒有真正意義上的隔離,一切都只是在文檔中。文章中間也提到過組件化與應(yīng)用集成的不同,引文:EAR或者WAR部署的是一個企業(yè)應(yīng)用,請注意EJB規(guī)范中明確說:The Enterprise JavaBeans architecture is a architecture for the development and deployment of component-based (distributed) business applications(EJB 2.x和3.x唯一的區(qū)別是2.x有distributed),它們有自己的應(yīng)用域,彼此相互隔離(簡單的看,它們有各自獨(dú)立的會話管理)。.NET也是有自己的應(yīng)用域概念。
根據(jù)上面所描述,結(jié)合我把組件化放置到模塊化和應(yīng)用集成之間的定位。組件化應(yīng)比模塊化更獨(dú)立,但比應(yīng)用集成結(jié)合得更加緊密。借助上面提到的那篇文章分析的,引文:基于應(yīng)用的部署導(dǎo)致了三個隔離問題:交互(界面)隔離、程序訪問隔離和數(shù)據(jù)隔離.來看看組件化、模塊化、應(yīng)用集成的區(qū)別,以更清晰的看清楚組件化的位置。
組件化既然是介于上面兩者之間的,那么這三個方面又該如何定位,如何實(shí)現(xiàn)呢?
1. 界面交互
我認(rèn)為用戶交互應(yīng)該統(tǒng)一,因?yàn)?strong>組件化的各個業(yè)務(wù)組件最終拼裝成同一套企業(yè)應(yīng)用,UI作為用戶操作接口,必須看起來是統(tǒng)一的而不是獨(dú)立的。這一點(diǎn)與模塊化實(shí)現(xiàn)的各種系統(tǒng)類似,雖然屬于不同的模塊但用戶界面使用起來始終如一。另外,開發(fā)和部署上我認(rèn)為應(yīng)該根據(jù)組件不同來分離。
于是矛盾出現(xiàn)了,既然要看起來統(tǒng)一,又要可以分開來開發(fā),可以分開來部署。首先如何保證不同的開發(fā)小組開發(fā)出的界面風(fēng)格一致。其次分開部署使用什么手段整合到一個界面中呢?
針對第一個問題我們可以模仿模塊化開發(fā)的經(jīng)驗(yàn),復(fù)雜一點(diǎn):使用統(tǒng)一的UI工具開發(fā);簡單一點(diǎn):也可以基于約定。至于UI整合的事情我們可能需要有一個門戶組件來搞定了。
2. 程序訪問
這個問題比較糾結(jié)。
基于“組件僅依賴于平臺運(yùn)行,而不依賴其他組件運(yùn)行”這個前提.組件之間的交互就不能像模塊化那樣直接訪問。那么像應(yīng)用集成那樣開放訪問接口如何呢?
我認(rèn)為也不妥。為什么呢?讓我們想一下系統(tǒng)集成發(fā)生的場景。某公司已經(jīng)有一套某業(yè)務(wù)領(lǐng)域的系統(tǒng),現(xiàn)在又要上另一套其他業(yè)務(wù)領(lǐng)域的系統(tǒng)。當(dāng)這兩套系統(tǒng)在業(yè)務(wù)上出現(xiàn)了交互時,找來兩套系統(tǒng)的開發(fā)商,制定方案,進(jìn)行二次開發(fā),彼此開放接口修改程序相互調(diào)用。從這里我們可以看出,這種方案首先從誕生的那天起就是一個出于無奈的方案。注定被結(jié)合的兩方不夠緊密,其次開放訪問接口存在一定的安全隱患。另外,加上我們前面留下的那個難題:“組件之間的交互在業(yè)務(wù)上存在著不可規(guī)范和不可窮盡的特點(diǎn)。”這樣的集成方案是不是不適合我們的組件呢?首先,組件之間會存在如此頻繁復(fù)雜的交互,我們需要更緊密的結(jié)合,或者說是無縫的結(jié)合。另外,我們在開發(fā)組件的時候,不可能預(yù)想到那么多的其他組件它們期望從我們這里得到什么,我們不可能事先為它們準(zhǔn)備那么多的服務(wù)接口。
那么程序間的訪問,又有什么樣的介于模塊化和應(yīng)用集成兩者之間的方案呢?這個平衡點(diǎn)在哪里呢?我有個還不太清晰的想法,這里提一下,大家來拍吧。
先說一下常規(guī)的方案.比較常規(guī)的想法,可能多數(shù)人(包括我)會想到引入總線,或類似于主板和插槽的概念,把我們的組件插上去,組件與總線結(jié)合,通過總線與其他組件實(shí)現(xiàn)交互。這樣做確實(shí)能實(shí)現(xiàn)交互和通信,可我總覺得這樣的方案不是最好的,組件的結(jié)合還是不夠直接不夠緊密,依然存在我們無法窮盡哪些服務(wù)需要提供給總線,供其他組件調(diào)用的問題。而且,既然是總線就有類似于帶寬的問題,當(dāng)業(yè)務(wù)高峰期,組件間的交互頻繁,勢必會發(fā)生擁堵,帶來效率問題.
我認(rèn)為我們需要更靈活、更直接的組裝結(jié)合.
我們來創(chuàng)造一個“粘合層”或者“膠水層”怎么樣?由“膠水層”來負(fù)責(zé)各個組件之間的交互和粘合問題.組件的組裝,我們經(jīng)常比喻成搭積木或者拼圖。但實(shí)際上我們不能夠像積木和拼圖那樣,事先定義出明確的尺寸大小和足夠的插槽或接口,我們的組件實(shí)際形狀是比較靈活的、形狀不一、大小不一的。對于這樣形狀體的組合,我認(rèn)為使用強(qiáng)力“膠水”來粘合比較合適。當(dāng)我們選定了兩個組件,并要將他們聯(lián)合起來使用的時候,我們在中間涂上一層“膠水”把他們粘合起來,“膠水”實(shí)際是一種導(dǎo)體,它作為信息傳輸?shù)慕橘|(zhì),在兩個組件中進(jìn)行程序的調(diào)用和數(shù)據(jù)的傳輸。某一個組件可能會與多個組件進(jìn)行結(jié)合交互,我們在它們之間分別加入“膠水”進(jìn)行組合,使他們之間各有單獨(dú)的組合介質(zhì),而不是統(tǒng)一通過唯一的總線。這樣可以讓組合更加靈活,交互更直接。
至于膠水層的實(shí)現(xiàn)問題,可能需要一些技術(shù)上的突破。需要進(jìn)一步的探討研究。目前考慮Python或者Ruby這樣的動態(tài)語言。這里存在有諸如:事務(wù)控制,同步異步,并發(fā)控制等問題,也需要進(jìn)一步研究。
另外,引入膠水層可能會對人員的布局產(chǎn)生一些影響。不僅僅有負(fù)責(zé)各種組件開發(fā)的開發(fā)團(tuán)隊(duì),還可能需要有負(fù)責(zé)膠水組合的實(shí)施團(tuán)隊(duì)(這個實(shí)施團(tuán)隊(duì)貌似技術(shù)門檻有些高,我們可能需要考慮做一個工具來減輕這個團(tuán)隊(duì)的技術(shù)門檻,使之盡可能多關(guān)注業(yè)務(wù),少關(guān)注技術(shù)。當(dāng)然,對于經(jīng)常組合的組件我們會積累下他們之間的“膠水”代碼來復(fù)用)。
3. 數(shù)據(jù)
介于模塊化與系統(tǒng)集成之間。我認(rèn)為各組件的業(yè)務(wù)數(shù)據(jù)應(yīng)該分別存儲,各個組件數(shù)據(jù)庫上實(shí)現(xiàn)大部分的數(shù)據(jù)自治。這部分自治的數(shù)據(jù)包括業(yè)務(wù)數(shù)據(jù)和元數(shù)據(jù),至于主數(shù)據(jù)考慮使用冗余的方式,通過引入主數(shù)據(jù)組件來同步分發(fā)給各個業(yè)務(wù)組件。注意,這里我們叫做“主數(shù)據(jù)組件”,而不叫做“主數(shù)據(jù)總線”,表示其在系統(tǒng)中的地位與其他組件無異。
關(guān)于查詢和統(tǒng)計(jì)分析。簡單的查詢,數(shù)據(jù)僅涉及本組件內(nèi)的,可以直接查詢本組件內(nèi)數(shù)據(jù)庫獲得。一些跨組件數(shù)據(jù)的查詢或者報(bào)表、報(bào)告,考慮進(jìn)行數(shù)據(jù)抽取進(jìn)入BI組件,利用BI組件進(jìn)行分析。
我簡單畫了一個基于業(yè)務(wù)組件的系統(tǒng)的布局圖,也順帶提一下關(guān)于容器的事情。
上面這些只是些想法,尚未形成實(shí)際的方案,這里先發(fā)出來拋個磚,大家集思廣益一下能扔塊玉回來就最好了。
提供該文檔的機(jī)構(gòu)為 OECP社區(qū),更多的博客文章可以到 OECP社區(qū)查看。該文檔附件歡迎各位轉(zhuǎn)載,但是在沒有獲得文章作者許可之前,不得對文章內(nèi)容或者版權(quán)信息進(jìn)行更改,版權(quán)歸OECP社區(qū)所有,僅此聲明。
轉(zhuǎn):http://www.oecp.cn/hi/slx/blog/1964
看了社區(qū)里的一些內(nèi)容,再加上平時跟同事們的交流和討論,對組件化業(yè)務(wù)系統(tǒng)的實(shí)現(xiàn)產(chǎn)生了一點(diǎn)想法。下面我說下我的想法,歡迎大家來拍磚討論。
我覺得目前大家對業(yè)務(wù)組件有一個共識:就是各個業(yè)務(wù)組件相對獨(dú)立,并且具有可組裝性和可插拔性。
每個組件的運(yùn)行僅依賴于平臺或者容器,組件與組件之間不存才直接的耦合關(guān)系。同時,組件與組件之間又并非絕對的獨(dú)立。組件經(jīng)過組裝后可以與其他的組件進(jìn)行業(yè)務(wù)上的交互。比如銷售組件與財(cái)務(wù)組件,一筆銷售業(yè)務(wù)的完成必定會產(chǎn)生一筆或幾筆財(cái)務(wù)的業(yè)務(wù),如銷售發(fā)票的開出和一筆新的應(yīng)收應(yīng)付或者現(xiàn)金銀行的記賬。又比如,采購與庫存管理,當(dāng)采購的需求被提出,那么是不是要先看看倉庫是不是有存貨呢?如果本倉庫沒有,是否允許從其他倉庫調(diào)撥呢?等等等等……,諸如此類的業(yè)務(wù)場景無法窮盡,而不同行業(yè)不同規(guī)模的用戶他們的業(yè)務(wù)過程又各自不同。
也就是說,組件之間的交互在業(yè)務(wù)上存在著不可規(guī)范和不可窮盡的特點(diǎn).這是個比較頭疼的問題,暫且記下,稍后再做討論。
另外,我的理解:組件化是介于模塊化與應(yīng)用系統(tǒng)集成之間的一個概念.關(guān)于組件化、模塊化、應(yīng)用的不同,社區(qū)中的一篇文章寫得很好。這篇文章的最后,提到了組件化不同于模塊化,引文:模塊化開發(fā)不同于組件開發(fā),模塊化開發(fā)只是在邏輯上做了切分,物理上(開發(fā)出的系統(tǒng)代碼)通常并沒有真正意義上的隔離,一切都只是在文檔中。文章中間也提到過組件化與應(yīng)用集成的不同,引文:EAR或者WAR部署的是一個企業(yè)應(yīng)用,請注意EJB規(guī)范中明確說:The Enterprise JavaBeans architecture is a architecture for the development and deployment of component-based (distributed) business applications(EJB 2.x和3.x唯一的區(qū)別是2.x有distributed),它們有自己的應(yīng)用域,彼此相互隔離(簡單的看,它們有各自獨(dú)立的會話管理)。.NET也是有自己的應(yīng)用域概念。
根據(jù)上面所描述,結(jié)合我把組件化放置到模塊化和應(yīng)用集成之間的定位。組件化應(yīng)比模塊化更獨(dú)立,但比應(yīng)用集成結(jié)合得更加緊密。借助上面提到的那篇文章分析的,引文:基于應(yīng)用的部署導(dǎo)致了三個隔離問題:交互(界面)隔離、程序訪問隔離和數(shù)據(jù)隔離.來看看組件化、模塊化、應(yīng)用集成的區(qū)別,以更清晰的看清楚組件化的位置。
用戶交互(界面) | 程序訪問 | 數(shù)據(jù) | |
模塊化 | 統(tǒng)一 | 模塊間直接依賴訪問 | 統(tǒng)一存儲 |
應(yīng)用 | 獨(dú)立 | 對外部開放訪問接口 | 獨(dú)立 |
組件化既然是介于上面兩者之間的,那么這三個方面又該如何定位,如何實(shí)現(xiàn)呢?
1. 界面交互
我認(rèn)為用戶交互應(yīng)該統(tǒng)一,因?yàn)?strong>組件化的各個業(yè)務(wù)組件最終拼裝成同一套企業(yè)應(yīng)用,UI作為用戶操作接口,必須看起來是統(tǒng)一的而不是獨(dú)立的。這一點(diǎn)與模塊化實(shí)現(xiàn)的各種系統(tǒng)類似,雖然屬于不同的模塊但用戶界面使用起來始終如一。另外,開發(fā)和部署上我認(rèn)為應(yīng)該根據(jù)組件不同來分離。
于是矛盾出現(xiàn)了,既然要看起來統(tǒng)一,又要可以分開來開發(fā),可以分開來部署。首先如何保證不同的開發(fā)小組開發(fā)出的界面風(fēng)格一致。其次分開部署使用什么手段整合到一個界面中呢?
針對第一個問題我們可以模仿模塊化開發(fā)的經(jīng)驗(yàn),復(fù)雜一點(diǎn):使用統(tǒng)一的UI工具開發(fā);簡單一點(diǎn):也可以基于約定。至于UI整合的事情我們可能需要有一個門戶組件來搞定了。
2. 程序訪問
這個問題比較糾結(jié)。
基于“組件僅依賴于平臺運(yùn)行,而不依賴其他組件運(yùn)行”這個前提.組件之間的交互就不能像模塊化那樣直接訪問。那么像應(yīng)用集成那樣開放訪問接口如何呢?
我認(rèn)為也不妥。為什么呢?讓我們想一下系統(tǒng)集成發(fā)生的場景。某公司已經(jīng)有一套某業(yè)務(wù)領(lǐng)域的系統(tǒng),現(xiàn)在又要上另一套其他業(yè)務(wù)領(lǐng)域的系統(tǒng)。當(dāng)這兩套系統(tǒng)在業(yè)務(wù)上出現(xiàn)了交互時,找來兩套系統(tǒng)的開發(fā)商,制定方案,進(jìn)行二次開發(fā),彼此開放接口修改程序相互調(diào)用。從這里我們可以看出,這種方案首先從誕生的那天起就是一個出于無奈的方案。注定被結(jié)合的兩方不夠緊密,其次開放訪問接口存在一定的安全隱患。另外,加上我們前面留下的那個難題:“組件之間的交互在業(yè)務(wù)上存在著不可規(guī)范和不可窮盡的特點(diǎn)。”這樣的集成方案是不是不適合我們的組件呢?首先,組件之間會存在如此頻繁復(fù)雜的交互,我們需要更緊密的結(jié)合,或者說是無縫的結(jié)合。另外,我們在開發(fā)組件的時候,不可能預(yù)想到那么多的其他組件它們期望從我們這里得到什么,我們不可能事先為它們準(zhǔn)備那么多的服務(wù)接口。
那么程序間的訪問,又有什么樣的介于模塊化和應(yīng)用集成兩者之間的方案呢?這個平衡點(diǎn)在哪里呢?我有個還不太清晰的想法,這里提一下,大家來拍吧。
先說一下常規(guī)的方案.比較常規(guī)的想法,可能多數(shù)人(包括我)會想到引入總線,或類似于主板和插槽的概念,把我們的組件插上去,組件與總線結(jié)合,通過總線與其他組件實(shí)現(xiàn)交互。這樣做確實(shí)能實(shí)現(xiàn)交互和通信,可我總覺得這樣的方案不是最好的,組件的結(jié)合還是不夠直接不夠緊密,依然存在我們無法窮盡哪些服務(wù)需要提供給總線,供其他組件調(diào)用的問題。而且,既然是總線就有類似于帶寬的問題,當(dāng)業(yè)務(wù)高峰期,組件間的交互頻繁,勢必會發(fā)生擁堵,帶來效率問題.
我認(rèn)為我們需要更靈活、更直接的組裝結(jié)合.
我們來創(chuàng)造一個“粘合層”或者“膠水層”怎么樣?由“膠水層”來負(fù)責(zé)各個組件之間的交互和粘合問題.組件的組裝,我們經(jīng)常比喻成搭積木或者拼圖。但實(shí)際上我們不能夠像積木和拼圖那樣,事先定義出明確的尺寸大小和足夠的插槽或接口,我們的組件實(shí)際形狀是比較靈活的、形狀不一、大小不一的。對于這樣形狀體的組合,我認(rèn)為使用強(qiáng)力“膠水”來粘合比較合適。當(dāng)我們選定了兩個組件,并要將他們聯(lián)合起來使用的時候,我們在中間涂上一層“膠水”把他們粘合起來,“膠水”實(shí)際是一種導(dǎo)體,它作為信息傳輸?shù)慕橘|(zhì),在兩個組件中進(jìn)行程序的調(diào)用和數(shù)據(jù)的傳輸。某一個組件可能會與多個組件進(jìn)行結(jié)合交互,我們在它們之間分別加入“膠水”進(jìn)行組合,使他們之間各有單獨(dú)的組合介質(zhì),而不是統(tǒng)一通過唯一的總線。這樣可以讓組合更加靈活,交互更直接。
至于膠水層的實(shí)現(xiàn)問題,可能需要一些技術(shù)上的突破。需要進(jìn)一步的探討研究。目前考慮Python或者Ruby這樣的動態(tài)語言。這里存在有諸如:事務(wù)控制,同步異步,并發(fā)控制等問題,也需要進(jìn)一步研究。
另外,引入膠水層可能會對人員的布局產(chǎn)生一些影響。不僅僅有負(fù)責(zé)各種組件開發(fā)的開發(fā)團(tuán)隊(duì),還可能需要有負(fù)責(zé)膠水組合的實(shí)施團(tuán)隊(duì)(這個實(shí)施團(tuán)隊(duì)貌似技術(shù)門檻有些高,我們可能需要考慮做一個工具來減輕這個團(tuán)隊(duì)的技術(shù)門檻,使之盡可能多關(guān)注業(yè)務(wù),少關(guān)注技術(shù)。當(dāng)然,對于經(jīng)常組合的組件我們會積累下他們之間的“膠水”代碼來復(fù)用)。
3. 數(shù)據(jù)
介于模塊化與系統(tǒng)集成之間。我認(rèn)為各組件的業(yè)務(wù)數(shù)據(jù)應(yīng)該分別存儲,各個組件數(shù)據(jù)庫上實(shí)現(xiàn)大部分的數(shù)據(jù)自治。這部分自治的數(shù)據(jù)包括業(yè)務(wù)數(shù)據(jù)和元數(shù)據(jù),至于主數(shù)據(jù)考慮使用冗余的方式,通過引入主數(shù)據(jù)組件來同步分發(fā)給各個業(yè)務(wù)組件。注意,這里我們叫做“主數(shù)據(jù)組件”,而不叫做“主數(shù)據(jù)總線”,表示其在系統(tǒng)中的地位與其他組件無異。
關(guān)于查詢和統(tǒng)計(jì)分析。簡單的查詢,數(shù)據(jù)僅涉及本組件內(nèi)的,可以直接查詢本組件內(nèi)數(shù)據(jù)庫獲得。一些跨組件數(shù)據(jù)的查詢或者報(bào)表、報(bào)告,考慮進(jìn)行數(shù)據(jù)抽取進(jìn)入BI組件,利用BI組件進(jìn)行分析。
我簡單畫了一個基于業(yè)務(wù)組件的系統(tǒng)的布局圖,也順帶提一下關(guān)于容器的事情。
上面這些只是些想法,尚未形成實(shí)際的方案,這里先發(fā)出來拋個磚,大家集思廣益一下能扔塊玉回來就最好了。
提供該文檔的機(jī)構(gòu)為 OECP社區(qū),更多的博客文章可以到 OECP社區(qū)查看。該文檔附件歡迎各位轉(zhuǎn)載,但是在沒有獲得文章作者許可之前,不得對文章內(nèi)容或者版權(quán)信息進(jìn)行更改,版權(quán)歸OECP社區(qū)所有,僅此聲明。
轉(zhuǎn):http://www.oecp.cn/hi/slx/blog/1964