分布式系統(tǒng)關(guān)注點(diǎn)——「高內(nèi)聚低耦合」詳解

如果這是第二次看到我的文章,歡迎訂閱z哥的公眾號(hào)(跨界架構(gòu)師)哦~

每周五11:45 按時(shí)送達(dá)阐斜。當(dāng)然了皱蹦,也會(huì)時(shí)不時(shí)加個(gè)餐~

本文長(zhǎng)度為3012字煤杀,建議閱讀8分鐘。


下面的這個(gè)場(chǎng)景你可能會(huì)覺(jué)得很熟悉(Z哥我又要出演了):

Z哥:@All 兄弟姐妹們沪哺,這次我這邊有個(gè)需求需要給「商品上架」增加一道審核沈自,會(huì)影響到大家和我交互的接口。大家抽空配合改一下辜妓,明天一起更新個(gè)版本枯途。

小Y:哥,我這幾天很忙啊籍滴,昨天剛配合老王改過(guò)促銷(xiāo)酪夷!

小X:行~當(dāng)一切已成習(xí)慣。

作為被通知人孽惰,如果在你的現(xiàn)實(shí)工作中也發(fā)生了類似事件晚岭,我相信哪怕嘴上不說(shuō),心里也會(huì)有不少想法和抱怨:“md勋功,改的是你坦报,我也要發(fā)布,好冤翱裥片择!”。


這個(gè)問(wèn)題的根本原因就是多個(gè)項(xiàng)目之間的耦合度過(guò)于嚴(yán)重要销。

越大型的項(xiàng)目越容易陷入到這個(gè)昭潭中,難以自拔夏块。

而解決問(wèn)題的方式就是進(jìn)行更合理的分層疏咐,并且持續(xù)保證分層的合理性。

一提到分層脐供,必然離不開(kāi)6個(gè)字「高內(nèi)聚」和「低耦合」浑塞。


什么是高內(nèi)聚低耦合

在z哥之前的文章中有多次提到,布式系統(tǒng)的本質(zhì)就是「分治」和「冗余」政己。

其中酌壕,分治就是“分解 -> 治理 -> 歸并”的三部曲。「高內(nèi)聚」卵牍、「低耦合」的概念就來(lái)源于此果港。

需要注意的是,當(dāng)你在做「分解」這個(gè)操作的時(shí)候糊昙,務(wù)必要關(guān)注每一次的「分解」是否滿足一個(gè)最重要的條件:不同分支上的子問(wèn)題辛掠,不能相互依賴,需要各自獨(dú)立释牺。

因?yàn)橐坏┌艘蕾囮P(guān)系萝衩,子問(wèn)題和父問(wèn)題之間就失去了可以被「歸并」的意義。

比如没咙,一個(gè)「問(wèn)題Z」被分解成了兩個(gè)子問(wèn)題猩谊,「子問(wèn)題A」和「子問(wèn)題B」。但是祭刚,解問(wèn)題A依賴于問(wèn)題B的答案牌捷,解問(wèn)題B又依賴于問(wèn)題A的答案。這不就等于沒(méi)有分解嗎袁梗?

題外話:這里的“如何更合理的分解問(wèn)題”這個(gè)思路也可以用到你的生活和工作中的任何問(wèn)題上宜鸯。


所以,當(dāng)你在做「分解」的時(shí)候遮怜,需要有一些很好的著力點(diǎn)去切入淋袖。

這個(gè)著力點(diǎn)就是前面提到的「耦合度」和「內(nèi)聚度」,兩者是一個(gè)此消彼長(zhǎng)的關(guān)系锯梁。

越符合高內(nèi)聚低耦合這個(gè)標(biāo)準(zhǔn)即碗,程序的維護(hù)成本就越低。為什么呢陌凳?因?yàn)橐蕾囋叫“粒髯缘淖兏鼘?duì)其他關(guān)聯(lián)方的影響就越小。

所以合敦,「高內(nèi)聚」和「低耦合」是我們應(yīng)當(dāng)持續(xù)不斷追求的目標(biāo)初橘。

題外話:耦合度,指的是軟件模塊之間相互依賴的程度充岛。比如保檐,每次調(diào)用方法 A 之后都需要同步調(diào)用方法 B,那么此時(shí)方法 A 和 B 間的耦合度是高的崔梗。

內(nèi)聚度夜只,指的是模塊內(nèi)的元素具有的共同點(diǎn)的相似程度。比如蒜魄,一個(gè)類中的多個(gè)方法有很多的共同之處扔亥,都是做支付相關(guān)的處理场躯,那么這個(gè)類的內(nèi)聚度是高的。


怎么做好高內(nèi)聚低耦合

做好高內(nèi)聚低耦合旅挤,思路也很簡(jiǎn)單:定職責(zé)踢关、做歸類、劃邊界谦铃。

首先耘成,定職責(zé)就是定義每一個(gè)子系統(tǒng)、每一個(gè)模塊驹闰、甚至每一個(gè)class和每一個(gè)function的職責(zé)瘪菌。

比如,在子系統(tǒng)或者模塊層面可以這樣嘹朗。

又比如师妙,在class或者function層面可以這樣。

我想這點(diǎn)大家平時(shí)都會(huì)有意識(shí)的去做屹培。

做好了職責(zé)定義后默穴,內(nèi)聚性就會(huì)有很大的提升,同時(shí)也提高了代碼/程序的復(fù)用程度褪秀。

至此蓄诽,我們才談得上「單一職責(zé)(SRP)」這種設(shè)計(jì)原則的運(yùn)用。


其次媒吗,做歸類仑氛。梳理不同模塊之間的依賴關(guān)系。

像上面提到的案例1可以歸類為3層:

基礎(chǔ)層:商品基礎(chǔ)服務(wù)闸英、會(huì)員基礎(chǔ)服務(wù)锯岖、促銷(xiāo)基礎(chǔ)服務(wù)

聚合層:購(gòu)物車(chē)服務(wù)、商品詳情服務(wù)甫何、登陸服務(wù)

接入層:快閃店API出吹、綜合商城API

案例2也可以歸類為3層:

數(shù)據(jù)訪問(wèn)層:訪問(wèn)會(huì)員表數(shù)據(jù)、訪問(wèn)會(huì)員積分表數(shù)據(jù)辙喂、訪問(wèn)會(huì)員等級(jí)表數(shù)據(jù)

業(yè)務(wù)邏輯層:會(huì)員登陸邏輯捶牢、會(huì)員使用積分邏輯、會(huì)員升級(jí)邏輯

應(yīng)用層:接收用戶輸入的賬戶密碼巍耗、接收用戶輸入的使用積分?jǐn)?shù)秋麸、接收用戶的付款信息



最后就是劃邊界。好不容易梳理清楚芍锦,為了避免輕易被再次破壞竹勉,所以需要設(shè)立好合理清晰的邊界飞盆。

否則你想的是這樣整齊娄琉。



實(shí)際會(huì)慢慢變成這樣混亂次乓。


那么應(yīng)該怎么劃邊界呢?


class和function級(jí)別孽水。這個(gè)層面可以通過(guò)codereview或者靜態(tài)代碼檢測(cè)工具來(lái)進(jìn)行票腰,可以關(guān)注的點(diǎn)比如:

調(diào)用某些class必須通過(guò)interface而不是implement

訪問(wèn)會(huì)員表數(shù)據(jù)的class中不能存在訪問(wèn)商品數(shù)據(jù)的function


模塊級(jí)別∨可以選擇以下方案:

給每一種類型的class分配不同project杏慰,打包到各自的dll(jar)中

每次代碼push上來(lái)的時(shí)候檢測(cè)其中的依賴是否有超出規(guī)定的依賴。例如炼鞠,不能逆向依賴(檢測(cè)dal是否包含bll)缘滥;不能在基礎(chǔ)層做聚合業(yè)務(wù)(檢測(cè)商品基礎(chǔ)服務(wù)是否包含其他基礎(chǔ)服務(wù)的dll(jar))。

系統(tǒng)級(jí)別谒主。及時(shí)識(shí)別子系統(tǒng)之間的調(diào)用是否符合預(yù)期朝扼,可以通過(guò)接入一個(gè)調(diào)用鏈跟蹤系統(tǒng)(如,zipkin)來(lái)分析請(qǐng)求鏈路是否合法霎肯。


讓邊界更清晰擎颖、穩(wěn)定的最佳實(shí)踐

很多時(shí)候不同的模塊或者子系統(tǒng)會(huì)被分配到不同的小組中負(fù)責(zé),所以z哥再分享幾個(gè)最佳實(shí)踐給你观游。它可以讓系統(tǒng)之間的溝通更穩(wěn)定搂捧。


首先是:模塊對(duì)外暴露的接口部分,數(shù)據(jù)類型的選擇上盡量做到寬進(jìn)嚴(yán)出懂缕。比如允跑,使用long代替byte之類的數(shù)據(jù)類型;使用弱類型代替強(qiáng)類型等等提佣。

舉個(gè)「寬進(jìn)嚴(yán)出」的例子:

//使用long代替byte之類的數(shù)據(jù)類型吮蛹。

void Add(long param1, long param2){

????if(param1 <1000&& param2 < 1000){? //先接收進(jìn)來(lái),到里面再做邏輯校驗(yàn)拌屏。

????????//do something...

????}

????else{

????????//do something...

????}

}

其次是:寫(xiě)操作接口潮针,接收參數(shù)盡可能少;讀操作接口倚喂,返回參數(shù)盡可能多每篷。

為什么呢?因?yàn)楹芏鄷r(shí)候端圈,寫(xiě)操作的背后會(huì)存在一個(gè)潛在預(yù)期焦读,是「準(zhǔn)確」。

準(zhǔn)確度和可信度有著很大的聯(lián)系舱权,只有更多的邏輯處理在自己掌控范圍內(nèi)進(jìn)行才能越具備「可信度」(當(dāng)然是職責(zé)范圍內(nèi)的邏輯矗晃,而不是讓商品服務(wù)去計(jì)算促銷(xiāo)的邏輯)。反之宴倍,上游系統(tǒng)一個(gè)bug就會(huì)牽連到你的系統(tǒng)中张症。

而讀操作背后的潛在預(yù)期是:「滿足」仓技。你得提供給我滿足我當(dāng)前需要的數(shù)據(jù),否則我的工作無(wú)法開(kāi)展俗他。

但是呢脖捻,在不同時(shí)期,客戶端所需要的數(shù)據(jù)可能會(huì)發(fā)生變化兆衅,你無(wú)法預(yù)測(cè)地沮。所以呢,不要吝嗇羡亩,返回參數(shù)盡可能多摩疑,用哪些,用不用是客戶端的事畏铆。


還可以做的更好的一些未荒,就是,在可以滿足的基礎(chǔ)上支持按需獲取及志∑牛客戶端需要返回哪些字段自己通過(guò)參數(shù)傳過(guò)來(lái),如此一來(lái)還能避免浪費(fèi)資源做無(wú)用的數(shù)據(jù)傳輸速侈。

題外話:對(duì)外露出的接口設(shè)計(jì)率寡,可以使用http + json 這種跨平臺(tái) + 弱類型的技術(shù)組合,可具備更好的靈活性倚搬。


實(shí)際上冶共,一個(gè)程序大多數(shù)情況下,在某些時(shí)刻是客戶端每界,又在某些時(shí)刻是服務(wù)端捅僵。站在一個(gè)完整程序的角度來(lái)提煉參數(shù)設(shè)計(jì)的思路就是:吃”的要少,“產(chǎn)出”的要多眨层。

題外話:有一些設(shè)計(jì)原則可以擴(kuò)展閱讀一下庙楚。

單一職責(zé)原則SRP(Single Responsibility Principle)

開(kāi)放封閉原則OCP(Open-Close Principle)

里式替換原則LSP(the Liskov Substitution Principle LSP)

依賴倒置原則DIP(the Dependency Inversion Principle DIP)

接口分離原則ISP(the Interface Segregation Principle ISP)


總結(jié)

本文z哥帶你梳理了一下「高內(nèi)聚低耦合」的本質(zhì)(來(lái)自于哪,意義是什么)趴樱,并且分享了一些該怎么做的思路馒闷。

可以看到「高內(nèi)聚」、「低耦合」其實(shí)沒(méi)有這個(gè)名字那么高端叁征。哪怕你現(xiàn)在正在工作的項(xiàng)目是一個(gè)單體應(yīng)用纳账,也可以在class和function的設(shè)計(jì)中體會(huì)到「高內(nèi)聚」、「低耦合」的奧妙捺疼。

來(lái)來(lái)來(lái)疏虫,接下去馬上開(kāi)始在項(xiàng)目中「刻意練習(xí)」起來(lái)吧~



「易伸縮」篇的相關(guān)文章:

分布式系統(tǒng)關(guān)注點(diǎn)——「無(wú)狀態(tài)」詳解




如果你喜歡這篇文章,可以點(diǎn)一下底部的「喜歡」。

這樣可以給我一點(diǎn)反饋卧秘。: )

謝謝你的舉手之勞尤蛮。


? 關(guān)于作者:張帆(Zachary,個(gè)人微信號(hào):Zachary-ZF)斯议。堅(jiān)持用心打磨每一篇高質(zhì)量原創(chuàng)。本文首發(fā)于公眾號(hào):「跨界架構(gòu)師(ID:Zachary_ZF)醇锚。

如果你是初級(jí)程序員哼御,想提升但不知道如何下手。又或者做程序員多年焊唬,陷入了一些瓶頸想拓寬一下視野恋昼。歡迎關(guān)注我的公眾號(hào)「跨界架構(gòu)師」,回復(fù)「技術(shù)」赶促,送你一份我長(zhǎng)期收集和整理的思維導(dǎo)圖液肌。

如果你是運(yùn)營(yíng),面對(duì)不斷變化的市場(chǎng)束手無(wú)策鸥滨。又或者想了解主流的運(yùn)營(yíng)策略嗦哆,以豐富自己的“倉(cāng)庫(kù)”。歡迎關(guān)注我的公眾號(hào)「跨界架構(gòu)師」婿滓,回復(fù)「運(yùn)營(yíng)」老速,送你一份我長(zhǎng)期收集和整理的思維導(dǎo)圖。

?定期發(fā)表原創(chuàng)內(nèi)容:架構(gòu)設(shè)計(jì)丨分布式系統(tǒng)丨產(chǎn)品丨運(yùn)營(yíng)丨一些深度思考凸主。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末橘券,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子卿吐,更是在濱河造成了極大的恐慌旁舰,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嗡官,死亡現(xiàn)場(chǎng)離奇詭異箭窜,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)衍腥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)绽快,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人紧阔,你說(shuō)我怎么就攤上這事坊罢。” “怎么了擅耽?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵活孩,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我乖仇,道長(zhǎng)憾儒,這世上最難降的妖魔是什么询兴? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮起趾,結(jié)果婚禮上诗舰,老公的妹妹穿的比我還像新娘。我一直安慰自己训裆,他們只是感情好眶根,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著边琉,像睡著了一般属百。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上变姨,一...
    開(kāi)封第一講書(shū)人閱讀 51,370評(píng)論 1 302
  • 那天族扰,我揣著相機(jī)與錄音,去河邊找鬼定欧。 笑死渔呵,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的砍鸠。 我是一名探鬼主播厘肮,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼睦番!你這毒婦竟也來(lái)了类茂?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤托嚣,失蹤者是張志新(化名)和其女友劉穎巩检,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體示启,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡兢哭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了夫嗓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片迟螺。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖舍咖,靈堂內(nèi)的尸體忽然破棺而出矩父,到底是詐尸還是另有隱情,我是刑警寧澤排霉,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布窍株,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏球订。R本人自食惡果不足惜后裸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望冒滩。 院中可真熱鬧微驶,春花似錦、人聲如沸开睡。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)士八。三九已至,卻和暖如春梁呈,著一層夾襖步出監(jiān)牢的瞬間婚度,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工官卡, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蝗茁,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓寻咒,卻偏偏與公主長(zhǎng)得像哮翘,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子毛秘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 原文地址 前言 高內(nèi)聚低耦合饭寺,是軟件工程中的概念,是判斷設(shè)計(jì)好壞的標(biāo)準(zhǔn)叫挟,主要是面向?qū)ο蟮脑O(shè)計(jì)艰匙,看類的內(nèi)聚性是否高,...
    精神病患者link常閱讀 1,132評(píng)論 1 0
  • 前言 高內(nèi)聚低耦合抹恳,是軟件工程中的概念员凝,是判斷設(shè)計(jì)好壞的標(biāo)準(zhǔn),主要是面向?qū)ο蟮脑O(shè)計(jì)奋献,看類的內(nèi)聚性是否高健霹,耦合度是否...
    王永迪閱讀 3,160評(píng)論 1 13
  • 概念 耦合性: 也稱塊間聯(lián)系糖埋。指的軟件系統(tǒng)結(jié)構(gòu)中各模塊間相互涼席緊密程度的一種度量焕梅。模塊之間聯(lián)系越緊密宰译,其耦合性就...
    簫聲_筱昇閱讀 800評(píng)論 0 1
  • 概述內(nèi)聚是從功能角度來(lái)度量模塊內(nèi)的聯(lián)系怕膛,一個(gè)好的內(nèi)聚模塊應(yīng)當(dāng)恰好做一件事庶溶。它描述的是模塊內(nèi)的功能聯(lián)系;耦合是軟件結(jié)...
    人總要靠自己_趁年輕去努力閱讀 4,055評(píng)論 1 14
  • 2019.1.27.星期日.天氣.晴. 二寶放假第九天垒棋。今天早上二寶因昨天晚上發(fā)燒吃藥睡的晚卒煞。我讓寶爸叫他起床給他...
    李德紅閱讀 210評(píng)論 0 0