1. 程式人生 > >耦合的三種形式

耦合的三種形式

耦合的三種形式

  • 不透明耦合,

    部件A直接或通過代理B驅動部件C,部件A知道部件C的存在

  • 單邊透明耦合,

    部件A驅動代理B,代理B驅動部件C,部件A不知道部件C的存在,部件C知道部件A的存在

  • 雙邊透明耦合。

    部件A驅動代理B,代理B驅動部件C,部件A、C相互不知道對方的存在

此處解釋一下“驅動”這個詞。 系統運作一定是有一個動力源的,同一時刻A,C兩個部件協作,其中一方一定是驅動方,另一方一定是被驅動方。有人可能擡槓說,物理上力是相互的,同一時刻A,C是互為驅動方,被驅動方的。實際上可以將這個時刻分兩個方向來觀察,如果你站在A的角度,將A看作驅動方,那麼C就是被驅動方,你求一個值F1;如果你站在C的角度看,將C看作驅動方,A看作被驅動方,你再求一個值F2。那麼F1 + F2 和你用其他方法求出來的結果是一樣的。

在上面對耦合的三種形式的描述中,我將部件A看作是驅動方,A是一個邏輯代號,在實際系統中,它可以代表任何實際部件。因此你可以站在任何實際部件的角度思考此部件和被它驅動的部件的耦合形式。

這三種耦合形式分別由低到高代表了兩個部件耦合的鬆散程度。

不透明耦合是耦合程度最緊密的,它要求部件A知道部件C的存在,並直接或通過代理驅動它,部件A是動力源(這和單邊透明不同,單邊透明驅動部件C的動力源是代理B)。通常來說,不透明耦合預示著部件A和C最多處於職能分離狀態,而時空上是緊耦合的。比如齒輪和傳動軸的不透明耦合;比如在主程式中呼叫log4j的logger.warn(),則主程式和日誌程式是不透明耦合的,雖然log4j將列印日誌的職能同主程式分離了,但主程式在時間和空間上都和log4j緊密耦合著。

單邊透明耦合較不透明耦合要鬆散,在這種形式下部件A不知道部件C的存在,但部件C知道部件A的存在,並且代理B會替代部件A來驅動部件C。往往這種形式的耦合,代理B是以工作方式1(將"部件和部件"的耦合拆為"部件和協議"的耦合)工作的。典型的例子就是AOP,切點不知道切面的存在,而切面知道切點的存在,切面被框架(代理B)所驅動。

雙邊透明耦合是耦合程度最鬆散的,在這種形式下,部件A不需要知道部件C的存在,部件C也不需要知道部件A的存在,代理B替代部件A驅動部件C。同樣,代理B是工作方式1。典型例子,Vue、React、Angular的雙向資料繫結,輸入框操作一個變數,文字框根據這個變數改變內容,輸入框不知道文字框的存在,文字框也不知道輸入框的存在,雙方通過框架(代理B)協作。還有RabbitMQ,訊息生產者不知道訊息消費者的存在,訊息消費者不知道訊息生產者的存在,雙方通過交換機(代理B)協作。

單邊透明耦合和雙邊透明耦合都使得部件A和部件C是在職能上分離的,時空上隔離的。單邊透明耦合優於不透明耦合的地方在於,它將被驅動方從驅動方中隔離出去,被驅動方不會對驅動方產生任何影響(如果有影響,則這個影響屬於驅動關係調換後的場景,本質上是從另一個角度思考的結果)。雙邊透明耦合強大的地方在於,協作雙方存在數量是任意的(包括存在與否),協作雙方的協作機制是任意的,所以它是目前我所知道的,耦合程度最低的一種協作形式。

總結:三種耦合形式,有其存在的必要性,但追求鬆散耦合的系統應儘可能的在三種耦合形式中向後選擇