早在2005年,當時Steve Vinoski還就職于IONA公司,他就發表過一篇關于
內聚(Cohesion)和
耦合(Coupling)的文章。在文中,他提到了這些年來
已識別的3種“
恰當的”內聚類型:
- 功能內聚(Functional Cohesion):一個模塊只做一件事。它們表現出了低耦合與高度重用。
- 順序內聚(Sequential Cohesion):一個模塊包含多個需按一定次序執行的任務。
- 通訊內聚(Communication Cohesion):一個模塊包含多個基于相同輸入的操作,但這些操作在執行次序方面沒有任何要求。
然后,他又提到了四種“糟糕的”內聚:
- 過程內聚(Procedural Cohesion):與順序內聚相似,只不過各個任務所處理的數據各有不同。正如Steve所說:“這種內聚常常是‘為降低耦合度,人為把活動分組’的結果”。
- 時間內聚(Temporal Cohesion):一個模塊里的任務僅在時間上相關。“如果有任務要換在別的時間執行,那么這種模塊會帶來維護上的難題。”
- 邏輯內聚(Logical Cohesion):一個模塊里的活動由于“看似具有共同的實現”而被聚集起來。
- 偶然內聚(Coincidental Cohesion):一個模塊里的任務的唯一共同之處,就是它們均在此模塊之中。
正如Steve所說:
正如同耦合(coupling)一樣,內聚(cohesion)對于分布式對象與服務來說仍然重要。例如,如果你僅僅因為一組方法具有相似的實現就把它們放在一個對象里,那么你將犯“創建邏輯內聚對象(logically cohesive object)”的錯誤。
該文最后總結:
考慮到向“新的”計算方式的轉變常常伴隨著對舊的方式的直接批評,所以如今對SOA的關注引起對分布式對象的激烈反對并不出乎意料。不幸的是,其實許多適合分布式對象系統的質量標準也同樣適用于分布式服務與SOA。因此,有些人為了順應潮流而被迫忽略它們是十分遺憾的。不過,也許不要緊,因為我們可以直接追溯到對象之前的時期,搞清楚像耦合和內聚這樣的度量標準,并重新運用它們。
這在近年來也許已經不怎么被注意了,直到Jim Webber最近寫了一篇關于“貧血的服務模型(Anemic Service Model)”的文章。Jim簡述了過去對良好的軟件工程實踐的討論,他說的一些話跟 Steve 先前的非常相似:
有 些軟件是高內聚、緊耦合的。這意味著,盡管它經過合理的設計,但由于存在緊密的相互依賴關系,所以不容易被修改。那是很糟糕的;而且很不幸地是,這在企業 應用中很常見。還記得若干年前的確給你留下深刻印象,但如今維護起來卻令你痛苦不堪的軟件嗎?原因就在于它是緊耦合的。 松耦合、低內聚的軟件是另一種糟糕的軟件。這意味著模塊之間少有明顯的相互依賴;但是,沒有一個模塊是在系統中某方面處 于權威地位的。這進而造成需用“散彈法(scattergun approach)”來解決持續的系統演化,因為即使很小的改動也會波及多個組件或系統。也就是我們今天所認識到的SOA。
接著,該文繼續討論目前的SOA思想完全與這一狀況相悖:
一方面,我們傾向于(而且確實在SOA那 幫人的慫恿之下)認為這種架構是非常符合目標的,因為它是極度松耦合的。既然每個組件或服務都與其他別的組件或服務沒有耦合,那么應該可以像玩樂高積木那 樣、按無數種方式來組織或調整它們。書上教我們用一組基礎服務來構建“業務服務(business services)”。事實上,我們甚至可以用BPM工具“選擇-點擊”來輕而易舉地達到那個目標,從而避免了如開發者與一直伴隨左右的變更管理這樣的開 銷。是嗎?
不。實際上根本不是。[……] 這是對架構的幻想,在真實世界的企業系統里是不可能的。實際上,一個不解決業務問題的服務根本沒有資格進入SOA。
現在這篇文章吸引了不少值得注意的評論。然而,由這篇文章引發的實質性爭論已蔓延到了別處, 尤其是Jean-Jacques Dubray的回應:
嗯,有人一直試圖單槍匹馬地用一種“面向其他架構(Something Else Oriented Architecture)”來推翻SOA, 那就是MEST支持者Jim Webber。[……] 我覺得他這篇文章純屬誤導。也許有些地方我理解不當,但Jim說的是內聚與松耦合的關系。[……] 在我看來,內聚(cohesion)聽起來是個不錯的工程原則,它很像“依賴結構矩陣(Dependency Structure Matrix)”。[……] 松耦合(loose coupling)的目標正是降低內聚。一個互聯的(connected)系統是不存在內聚的。內聚和耦合不可能同時存在。即使在英語里,把這兩個詞聯系 在一起也是很糟糕的。
松耦合的目標,是使得在不同時間、用不同技術、具有不同安全模型的代碼片斷可以一同工作。
SOA是 要遠離內聚的系統、轉而支持更廣泛的重用場景。多層內聚的系統提供“多層”(像庫一樣的)重用模型:上層可以重用下層。不幸的是,它強迫我們以一種與理想 的信息系統架構不兼容的方式來創建系統。問題出在內聚,而解決之道在于松耦合。Jim,你真以為人們都在試圖“把東西放在一個模塊里”嗎?
Jean-Jacques提出,盡管內聚是一個被充分理解的軟件工程原則,不過它跟“當代”SOA并不相關:
有些人老拿他們5年前形成的觀念來看“SOA”,而那只是被他們自己錯誤理解的SOA,這種情形讓我覺得越來越不愉快。Jim所展現的是一幅陳舊的、并不能代表2008年的SOA的情景。
之后,Jean-Jacques 又繼續討論了Steve最初那篇文章:
…… 對于服務的接口與實現設計,內聚(cohesion)完全是一種沒有必要的約束,它實際上會降低一個服務的重用程度、并減弱它參與不同組裝的能力。也許我 們該對現代松耦合的概念作一些了解了,比如:雙向接口(bi-directional interfaces)、組裝(assemblies)、編制語言(orchestration languages)、可擴展及語義可達的數據結構(extensible and semantically accessible data structures)。過去設計出那些古老的編程技巧,就是因為編程模型里沒有這些概念。
但是爭論仍在繼續。內聚跟SOA是不是本質對立的?例如,我們是否需要重寫軟件工程書籍以涵蓋跟SOA有關的內聚?當然,內聚本身并無壞處;不過,也許內聚跟耦合一樣是分不同程度的,而且不能搞一刀切?
本文轉自infoQ中文站 作者 Mark Little 譯者 徐涵
標簽: 技術趨勢, SOA