問題一:
平時在設計類的時候往往會遇到以下情況,類A依賴於類B,同時類B又依賴於類A,這樣就會造成循環相依性。
如果在類中存在循環相依性,就會導致,如果A中有改變可能會影響B,同時B如果有變化也會影響A(個人觀點)。
在這個過程中,我又抽象出一個新的類C,這個類用來存放類A和類B相互依賴的部分,當A需要調用類B,在這個模型中可以直接去調用C。但是此時類C是不會去依賴類A和類B,我覺得這是一個痛點,如果在不依賴類B和類A的前提下,完成以前一樣的邏輯(這裡我認為會存在很多重複的代碼)。
Q:在設計過程中,循環相依性是否是允許的?如何解決循環相依性?
問題二:
平時我們在用spring寫商務邏輯的時候,當Service A依賴Service B和Service C,Service B依賴Service C。每當這個時候我就會有強迫症,我想把Service B 對Service C的依賴幹掉。在A中直接通過傳參的方式把Service C傳給Service B
如上所示,感覺在平時用spring架構的時候一些調用棧會很奇怪:
public class A{ private C c; private B b; public void methodA(){ c.methodC(); b.methodB(); } } public class B{ private C c; public void methodB(){ c.methodC(); doSomething(); } }
如上代碼.每當這個時候我都想把在A中c.methodC()
的結果傳回值通過參數傳給B.methodB()
,但是這樣會導致methodB()方法中多了一個參數。感覺在設計上又不是特別合理,因為我覺得在調用B.methodB()
的時候是不需要感知C的存在的。
Q:怎麼用物件導向的角度去理解問題二這個情境。
謝謝
回複內容:
問題一:
平時在設計類的時候往往會遇到以下情況,類A依賴於類B,同時類B又依賴於類A,這樣就會造成循環相依性。
如果在類中存在循環相依性,就會導致,如果A中有改變可能會影響B,同時B如果有變化也會影響A(個人觀點)。
在這個過程中,我又抽象出一個新的類C,這個類用來存放類A和類B相互依賴的部分,當A需要調用類B,在這個模型中可以直接去調用C。但是此時類C是不會去依賴類A和類B,我覺得這是一個痛點,如果在不依賴類B和類A的前提下,完成以前一樣的邏輯(這裡我認為會存在很多重複的代碼)。
Q:在設計過程中,循環相依性是否是允許的?如何解決循環相依性?
問題二:
平時我們在用spring寫商務邏輯的時候,當Service A依賴Service B和Service C,Service B依賴Service C。每當這個時候我就會有強迫症,我想把Service B 對Service C的依賴幹掉。在A中直接通過傳參的方式把Service C傳給Service B
如上所示,感覺在平時用spring架構的時候一些調用棧會很奇怪:
public class A{ private C c; private B b; public void methodA(){ c.methodC(); b.methodB(); } } public class B{ private C c; public void methodB(){ c.methodC(); doSomething(); } }
如上代碼.每當這個時候我都想把在A中c.methodC()
的結果傳回值通過參數傳給B.methodB()
,但是這樣會導致methodB()方法中多了一個參數。感覺在設計上又不是特別合理,因為我覺得在調用B.methodB()
的時候是不需要感知C的存在的。
Q:怎麼用物件導向的角度去理解問題二這個情境。
謝謝
循環相依性當然是允許的,沒有任何規定說依賴只能是單向的。看看設計模式中的中介者、觀察者等模式,它們就是典型的循環相依性關係。以觀察者模式為例:訂閱者會依賴觀察者,觀察者需要通知訂閱者所以也要依賴它們。
不能這樣做。如果不是依賴關係設計有問題,那麼A依賴B和C、B依賴C說明A和B確實需要C。如果像你說的那樣把B對C的依賴幹掉,那麼B就沒有存在的必要了,此時B將退化為A的“附屬類”,或者說是A的“專用方法類”。也就是說,B的可複用性就會大打折扣,如果以後有其他類,比如D,也需要用到B的話,那麼D將不得不也依賴C,這就把對B和C的依賴綁死了,但D未必需要C才能幹活啊,僅僅是為了“滿足”B就必須先弄一個C,是不是很奇怪?(如果D跟A一樣確實也需要C那是可以的,這裡說的是D本身不需要C的情況)
所以,首先確定B是否確實需要C,如果答案是肯定的,那就安心地這麼幹吧。
1、相互依賴確實是代碼中讓人糾結的壞味道,沒有更好的設計方案的情況下,只能盡量不讓這種混亂擴散到其他類。
2、對於分層設計,我個人是允許同一層的類之間相互依賴的,比如存在 Service 層和 DAO 層,前者依賴後者,而後者內部的類也可以相互依賴,但絕不允許 DAO 層的類調用 Service 層,一旦出現這種意願,說明這部分邏輯本來就應該放在 Service 層。