2009-06-14 48 views
4

我最近在爲我的主要個人項目尋找一些依賴關係圖,並且我注意到我在嵌套命名空間中的對象之間存在相互依賴關係。例如,我在MyNamespace.Foo中有一個對象,它在MyNamespace.Foo.Interfaces中實現了一個通用接口,該對象作爲接口中的通用參數。相互依賴的子/父命名空間代碼味道?

namespace MyNamespace.Foo 
{ 
    internal class Foo : MyNamespace.Foo.Interfaces.IFoo<Foo> 
    { } 
} 

在這種情況下。依賴分析工具(VS2010 beta)合理地將接口的通用「實例化」(出於討論的緣故,我知道這不是C++)作爲Interfaces命名空間的成員,然後依賴於它的父命名空間。

經過我的一些考慮後,我或多或少地得出結論,我的現有設計在我的特殊情況下是一種代碼味道。我應該將Interfaces命名空間合併到父Foo命名空間中。 (如果我希望它們通過IFoo使用Foo,要求客戶端向接口命名空間鑽取額外的圖層是愚蠢的。)然而,在一般情況下,這是否正確?

應如何管理內部名稱空間依賴關係?應該「更廣泛」的命名空間(如MyNamespace.Foo一般依賴於「窄」的命名空間(如MyNamespace.Foo.Interfaces),還是應該窄些命名空間依賴於更加廣泛的問題?或者是有一些更好的,更微妙的答案嗎?

回答

2

在特定的情況下,關於你的榜樣,我會合並Interfaces命名空間到父命名空間

一般來說,我認爲狹窄的命名空間應該依賴於更廣泛的類或接口,或者是共享父命名空間的子類。通常情況下,如果您安排了命名空間,以便模型名稱空間具有共享的類或接口,以描述您的代碼嘗試解決的問題的模型,請參閱

我還應該注意到,我不認爲這些規則必然適用於第三方依賴項。例如,取決於代碼中來自Spring.NET中狹窄名稱空間的代碼不會構成代碼異味。

2

如果你想從實現中分離接口,可能會並行MyNamespace.Foo.Interfaces和MyNamespace.Foo.Implementation命名空間。

默認似乎是一個命名空間相當於一個包或組件:如此FooBar將分別爲foo.dllbar.dll的命名空間。

如果我想要更高級別的分組,我會向名稱空間添加前綴:例如,MyCorp.Server.Foo是由MyCorp生成的服務器端foo.dll的名稱空間。

請注意,我要添加前綴,而不是後綴:所以MyCorp.Server.Foo而不是Foo.Server.MyCorp。這些結構化命名空間對應於包含源代碼和項目的文件夾/目錄結構。

默認情況下,包中的所有文件都具有相同的名稱空間(例如foo.dll中的所有代碼都屬於MyCorp.Server.Foo名稱空間)。如果我添加了一個後綴,這就會從程序集的其餘部分隱藏該代碼。例如,MyCorp.Server.Foo.EditorTransactions名稱空間中的代碼存在於foo.dll中,但foo.dll中的大多數其他代碼都看不到(除了明確使用MyCorp.Server.Foo.EditorTransactions的代碼外)。