2009-07-16 56 views
11

我只是在閱讀敏感原理,模式和實踐在C#由R.馬丁和M.馬丁,他們建議在他們的書,保持所有的接口在一個單獨的項目,例如。 接口組織接口

舉個例子,如果我有一個項目,包含我所有的自定義GUI類,我將保持其接口在接口項目。具體來說,我有一個在 CustomButton類,我會保持在接口 ICustomButton接口。

的優點是,這需要一個ICustomButton任何類並不需要,但只對重量輕得多接口項目本身的參考。

此外,應在項目變更一類,從而導致它被重建,只有項目直接參照的CustomButton需要重新編譯,而那些指ICustomButton可能會保持不變。

我理解的概念,但看問題:

可以說我有這個接口:

public interface ICustomButton 
{ 
    void Animate(AnimatorStrategy strategy); 
} 

正如你所看到的,它是指AnimatorStrategy,這是一個具體的類,因此將坐在不同的項目,讓我們打電話動畫。 現在界面工程需要參考動畫。另一方面,如果動畫使用在接口中定義的接口,則需要參考它。

循環依賴 - 「我們來了」。

對於這個問題,我看到的唯一解決方案是,接口中定義的所有方法都接受本身爲接口的輸入。試圖實現這一點,很可能會產生多米諾骨牌效應,並且很快需要一個接口來實現即使是最基本的類。

我不知道我是否願意在開發中處理這種開銷。

有什麼建議嗎?

回答

16

小心永遠,永遠,永遠 - 特別是在所有的附近,沒有,或每一個。

如果您總是你們接口的所有在單獨的程序?不 - 不一定。

您是否應該將希望實現代碼的外部使用者的接口放在可能的位置?如果您希望項目中的多個程序集依賴它們,我會將接口放到外部程序集中 - 這可以幫助中斷耦合依賴關係。我也使用這種做法來解決循環引用問題,其中程序集需要知道另一個接口。

我不把接口只在一個項目中在一個單獨的程序集中使用。當我的項目相對較小時,我也不會將接口提升到它們自己的組裝中,或者如果沒有依賴它們的組件,則不打算使用這些接口。

至於你提出的例子 - 我建議你考慮不從接口引用系統中的類。只要有可能,我嘗試讓接口只引用其他接口 - 這會使事情相對解耦。你不能總是實現這一點 - 所以當你有這些類型的接口時 - 你必須讓它們保持它們所依賴的程序集。

如果您決定將接口放入單獨的部件中 - 則不必將它們全部放入單個部件中。您可能希望按照其預期用法將其分解出來 - 這樣消費者就可以僅僅引入與特定功能域相關的接口。

3

簡單的答案是AnimatorStrategy也應該是一個接口。 AnimatorStrategy的實現位於Animation項目中,但接口將位於AnimationInterfaces或Interfaces(根據需要)項目中。

我不一定有一個接口項目,但每個功能分組。 Animation的客戶端會引用AnimationInterfaces,Gui的客戶端會引用GuiInterfaces。

這樣你就可以保留你的合同,而不用混淆任何實現。

爲了什麼值得我更喜歡用命名約定來換個角度。將接口放入Animation中,並將實現放入AnimationImpl(或類似的)中。這樣你就引用了功能名稱。

-2

如何定義一個接口與採用泛型類型的方法?例如。

public interface IThing 
{ 
    int DoMyThing<T>(T variable); 
} 

如果您需要在T variable一些限制,你可以這樣做:

int DoMyThing<T>(T variable) where T : IOtherInterface; 

IOtherInterface也是在你的界面項目中定義。然後,只要您的特定類繼承IThingIOtherInterface,就可以使用DoMyThing方法並傳入特定類的實例,而不會產生循環依賴。您的代碼可能變爲:

public interface ICustomButton 
{ 
    void Animate<T>(T strategy) where T : IAnimateable; 
} 

該接口沒有提及具體類AnimatorStrategy

+1

這有什麼關係? O_o – 2009-07-16 13:49:57

+1

這是一個好主意,但看起來更像是對我的破解。接口在那裏拼出契約。 T如何闡明期望的策略?如果我有可以註冊,我不需要T. – 2009-07-16 14:39:48

1

我認爲循環依賴可能是不可避免的,即使你將所有聲明爲接口也是不可避免的,因爲在程序集Foo中可能有一個方法需要一個參數IBar和一個帶有參數IFoo的程序集Bar中的方法。

我想說這裏沒有通用的配方,但是你應該使用「常識」來根據需要劃分組件中的接口。