作者:楊博鏈接:https://www.zhihu.com/question/21386172/answer/54476702來源:知乎著作權(quán)歸作者所有秧均。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)傀缩,非商業(yè)轉(zhuǎn)載請注明出處。以前狸捕,我寫代碼時,我考慮模塊(本文中的模塊就是指單個源文件)的單向依賴關(guān)系撵割,考慮接口的正交性和緊湊性奠宜。我覺得我在做低耦合的好設(shè)計。
然而嚷那,我發(fā)現(xiàn)其他程序員寫的代碼依賴關(guān)系混亂胞枕,接口臃腫,但他們?nèi)匀挥X得自己寫的代碼耦合很低魏宽,設(shè)計很好腐泻。我這才發(fā)現(xiàn),我理解的耦合和他們理解的不一樣队询。他們理解的低耦合就是把代碼提出來派桩,讓代碼不要“亂”。然而蚌斩,對于什么是“耦合”窄坦、什么是“亂”,他們并不知道有什么客觀標(biāo)準(zhǔn)可以度量凳寺。
所以鸭津,現(xiàn)在我相信“耦合”是個有歧義的壞詞,“低耦合”是個程序員經(jīng)常誤用的理論肠缨。我建議逆趋,設(shè)計架構(gòu)、考察模塊之間關(guān)系時晒奕,不要用“耦合”闻书、“亂”這些無法度量的詞語名斟,而應(yīng)該改用以下三個可以度量的指標(biāo):依賴、正交性魄眉、緊湊性砰盐。
依賴和耦合的最大區(qū)別在于,當(dāng)我們說“A和B耦合”時坑律,在字面含義中岩梳,A和B二者平等。然而晃择,正確的模塊關(guān)系根本不應(yīng)該平等冀值,而應(yīng)該是單向依賴才對。所以我們應(yīng)該說“A依賴B”宫屠,這樣含義要清楚得多列疗。A依賴B意味著,A模塊可以調(diào)用B模塊暴露的API浪蹂,但B模塊絕不允許調(diào)用A模塊的API抵栈。單向依賴是紅線,好的設(shè)計一定不會違反這條紅線坤次。
注意:根據(jù)實質(zhì)重于形式**原則竭讳,本文中的“依賴”指人腦中的依賴而不是編譯器的依賴。只要程序員編寫模塊A時浙踢,需要知道模塊B的存在,需要知道模塊B提供哪些功能灿渴,A對B依賴就存在洛波。甚至就算通過所謂的依賴注入、命名查找之類的“解耦”手段骚露,讓模塊A不需要import B或者include "B.h"蹬挤,人腦中的依賴仍舊一點都沒有變化。唯一的作用是會騙過后文會提到的代碼打分工具棘幸,讓工具誤以為兩個模塊間沒有依賴焰扳。
所以 @翟志軍
的例子中的解耦只是在自娛自樂兜圈子而已。因為不管你用什么技術(shù)手段误续,Configuration的調(diào)用方程序員總是需要知道配置項的具體業(yè)務(wù)含義才能用啊吨悍。
很多程序員覺得“耦合”是壞事,愛寫兜圈子的代碼來消除所謂的“耦合”蹋嵌。但是我們改用“依賴”術(shù)語后育瓜,我們就發(fā)現(xiàn)單向依賴不是壞事,根本不必費心消除栽烂,因為躏仇,真正的重點是恋脚,依賴關(guān)系中,被依賴方暴露的接口能不能足夠“正交”和“緊湊”焰手。
正交性是指一個模塊提供的API中糟描,多個方法之間是否有重復(fù)的功能。如果有重復(fù)功能书妻,正交性就差船响。通常,正交性高的模塊更穩(wěn)定驻子,不會因為上層業(yè)務(wù)變化而被迫修改代碼灿意。好的API內(nèi)部的多個方法之間不應(yīng)該有任何重復(fù)功能,只實現(xiàn)正交的機制崇呵。
如果感覺拆得太細(xì)使用不便缤剧,應(yīng)該在底層API之外包裝出一層Helper、Utility組成的膠水層域慷。膠水層調(diào)用底層原語API來實現(xiàn)常用模式供上層使用荒辕。對于膠水層中的模塊,對正交性的要求可以稍低一些犹褒。注意上層代碼既可以直接調(diào)用正交的底層API抵窒,又可以調(diào)用膠水層的常用模式。
緊湊性是指一個模塊提供的API中叠骑,公有方法總數(shù)必須很少李皇,每個方法的參數(shù)也必須很少≈婕希《Unix編程藝術(shù)》上說一個模塊不要超過7個方法掉房,不然就很難理解。但我實踐中發(fā)現(xiàn)慰丛,我一般編寫的模塊卓囚,公有方法通常不超過3個。
總之诅病,單向依賴哪亿、正交性、緊湊性這三個指標(biāo)都很務(wù)實贤笆,有客觀方法可以度量蝇棉。我覺得也許可以代替“低耦合”這種“公說公有理婆說婆有理”的務(wù)虛理論。比如前兩天我們ThoughtWorks的咨詢師郵件列表中就有人分享一些工具芥永,用上述標(biāo)準(zhǔn)自動檢查代碼質(zhì)量银萍。那么將來你和別的程序員約架,你要噴對方代碼寫得爛恤左,你就有了依據(jù)贴唇,因為你可以直接用工具給代碼打分搀绣。
另外,將來如果有同事或者網(wǎng)友在討論編程時戳气,用了“耦合”链患、“解耦”、“亂”之類的混亂術(shù)語瓶您,你可以把這篇文章發(fā)給他看麻捻,然后鄙視他。