之前組內(nèi)同學(xué)問我耦合的關(guān)系,我沒給對方講清楚,今天借這個機(jī)會來深入講講模塊之間的耦合關(guān)系這個事情。
本文將用圖文詳細(xì)講解七種耦合的不同之處。
高內(nèi)聚與低耦合是每個軟件開發(fā)者追求的目標(biāo),那么內(nèi)聚和耦合分別是什么意思呢?
內(nèi)聚是從功能角度來度量模塊內(nèi)的聯(lián)系,一個好的內(nèi)聚模塊應(yīng)當(dāng)恰好做一件事。它描述的是模塊內(nèi)的功能聯(lián)系。
耦合是軟件結(jié)構(gòu)中各模塊之間相互連接的一種度量,耦合強(qiáng)弱取決于模塊間接口的復(fù)雜程度、進(jìn)入或訪問一個模塊的點(diǎn)以及通過接口的數(shù)據(jù)。
不同模塊之間的關(guān)系就是耦合,根據(jù)耦合程度可以分為7種,耦合度依次變低。
下面我們來說說每種耦合是什么,開始之前先來說下要實現(xiàn)的功能。m1和m2是兩個獨(dú)立的模塊,其中m2種會顯示m1的輸入,m1會顯示m2的輸入。
很顯然,m1和m2兩個模塊之間會有一些聯(lián)系(耦合),你也可以想想如何實現(xiàn)這個功能,下面用7種不同的方式來實現(xiàn)這個功能。
注:項目的代碼我放到了github,項目的demo,可以在這里查看。
內(nèi)容耦合是最緊的耦合程度,一個模塊直接訪問另一模塊的內(nèi)容,則稱這兩個模塊為內(nèi)容耦合。
為了實現(xiàn)功能,我們將m1的輸入放到m2.m1input上,將m2的輸入放到m1.m2input上。
// m1.js
root.m2.m1input = this.value;
m2.update();
// m2.js
root.m1.m2input = this.value;
m1.update();
PS:不知道誰會這么寫代碼,除了我為了做演示之外。。。
一組模塊都訪問同一個全局?jǐn)?shù)據(jù)結(jié)構(gòu),則稱之為公共耦合。
在這種case中,m1和m2將自己的輸入放到全局的data上。
// m1.js
root.data.m1input = this.value;
m2.update();
// m2.js
root.data.m2input = this.value;
m1.update();
一組模塊都訪問同一全局簡單變量,而且不通過參數(shù)表傳遞該全局變量的信息,則稱之為外部耦合。外部耦合和公共耦合很像,區(qū)別就是一個是簡單變量,一個是復(fù)雜數(shù)據(jù)結(jié)構(gòu)。
在這種case中,m1和m2都將自己的輸入放到全局上。
// m1.js
root.m1input = this.value;
m2.update();
// m2.js
root.m2input = this.value;
m1.update();
模塊之間傳遞的不是數(shù)據(jù)信息,而是控制信息例如標(biāo)志、開關(guān)量等,一個模塊控制了另一個模塊的功能。
從控制耦合開始,模塊的數(shù)據(jù)就放在自己內(nèi)部了,不同模塊之間通過接口互相調(diào)用。
在這個case中,得增加一個需求,就是當(dāng)m1的輸入為空時,隱藏m2的顯示信息。
// m1.js
root.m1input = this.value;
m2.update();
m2.toggle(!!this.value); // 傳遞flag
上面的代碼中m1直接控制了m2的顯示和隱藏。
調(diào)用模塊和被調(diào)用模塊之間傳遞數(shù)據(jù)結(jié)構(gòu)而不是簡單數(shù)據(jù),同時也稱作特征耦合。
在這個case中,m1傳給m2的是一個對象。
// m1.js
me.m1input = this.value;
m2.update(me); // 傳遞引用
// m2.js
me.m2input = this.value;
m1.update(me);
調(diào)用模塊和被調(diào)用模塊之間只傳遞簡單的數(shù)據(jù)項參數(shù)。相當(dāng)于高級語言中的值傳遞。
在這個case中,m1傳給m2的是一個簡單數(shù)據(jù)結(jié)構(gòu)。
// m1.js
me.m1input = this.value;
m2.update(me.m1input); // 傳遞值
// m2.js
me.m2input = this.value;
m1.update(me.m2input);
兩個模塊之間沒有直接關(guān)系,它們之間的聯(lián)系完全是通過主模塊的控制和調(diào)用來實現(xiàn)的。耦合度最弱,模塊獨(dú)立性最強(qiáng)。
子模塊無需知道對方的存在,子模塊之間的聯(lián)系,全部變成子模塊和主模塊之間的聯(lián)系。
在這個case種,增加一個index.js作為主模塊。
// index.js
var m1 = root.m1;
var m2 = root.m2;
m1.init(function (str) {
m2.update(str);
});
m2.init(function (str) {
m1.update(str);
});
// m1.js
me.m1input = this.value;
inputcb(me.m1input); // inputcb是回調(diào)函數(shù)
// m2.js
me.m2input = this.value;
inputcb(me.m2input);
其實關(guān)于內(nèi)聚也分為很多種,如下所示,如果你感興趣可以自己研究研究,我們下次再來分享內(nèi)聚的問題。
希望你看完上面的文章,搞懂了耦合的種類,也希望你以后能使用非直接耦合這種方式來寫代碼,祝好。
更多建議: