耦合的三種形式框架
不透明耦合,代理
部件A直接或經過代理B驅動部件C,部件A知道部件C的存在日誌
單邊透明耦合,it
部件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,切點(A)不知道切面(C)的存在,而切面(C)知道切點(A)的存在,切面(C)被框架(代理B)所驅動。因爲切點對切面不透明,因此切面和切點耦合,但切點不和切面耦合。這實際上意味着,當切點發生變化時,它並不對切面的故障負責。切點也沒有和框架達成協議,因此對切點來講,框架和切面都是透明的。故叫單邊透明耦合。
雙邊透明耦合是耦合程度最鬆散的,在這種形式下,部件A不須要知道部件C的存在,部件C也不須要知道部件A的存在,代理B替代部件A驅動部件C。一樣,代理B是工做方式1。典型例子,Vue、React、Angular的雙向數據綁定,輸入框操做一個變量,文本框根據這個變量改變內容,輸入框不知道文本框的存在,文本框也不知道輸入框的存在,雙方經過框架(代理B)協做。還有RabbitMQ,消息生產者不知道消息消費者的存在,消息消費者不知道消息生產者的存在,雙方經過交換機(代理B)協做。
單邊透明耦合和雙邊透明耦合都使得部件A和部件C是在職能上分離的,時空上隔離的。單邊透明耦合優於不透明耦合的地方在於,它將被驅動方從驅動方中隔離出去,被驅動方不會對驅動方產生任何影響(若是有影響,則這個影響屬於驅動關係調換後的場景,本質上是從另外一個角度思考的結果)。雙邊透明耦合強大的地方在於,協做雙方存在數量是任意的(包括存在與否),協做雙方的協做機制是任意的,因此它是目前我所知道的,耦合程度最低的一種協做形式。
總結:三種耦合形式,有其存在的必要性,但追求鬆散耦合的系統應儘量的在三種耦合形式中向後選擇