我们应该将接口相对于其实现者放在哪个命名空间中?

时间:2020-03-06 14:51:10  来源:igfitidea点击:

具体来说,当我们创建接口/实现对时,并且没有组织上的首要问题(例如,接口应该放在不同的程序集中,即,根据架构的建议),我们是否有默认的方式在名称空间/命名方案?

这显然是一个更多基于意见的问题,但我认为有些人对此事的思考更多,我们都可以从他们的结论中受益。

解决方案

我通常要做的是在层次结构中高层创建一个Interfaces命名空间,并将所有接口放在其中(我不费心在其中嵌套其他命名空间,因为这样我最终会得到许多只包含一个接口的命名空间)。

Interfaces
|--IAnimal
|--IVegetable
|--IMineral
MineralImplementor
Organisms
|--AnimalImplementor
|--VegetableImplementor

这只是我过去所做的方式,并且我并没有遇到很多问题,尽管可以承认,这可能会使其他坐着我的项目的人感到困惑。我很想知道其他人在做什么。

我通常将接口保留在与具体类型相同的名称空间中。

但是,这只是我的意见,名称空间布局是非常主观的。

Animals
|
| - IAnimal
| - Dog
| - Cat
Plants
|
| - IPlant
| - Cactus

通过将一种或者两种类型移出主名称空间并不能真正获得任何收益,但是我们确实增加了对另外一个using语句的需求。

答案取决于意图。

  • 如果我们打算让命名空间的使用者在具体实现上使用接口,则建议我们将接口放在顶级命名空间中,并将实现放在子命名空间中
  • 如果使用者要同时使用两者,请将它们放在相同的名称空间中。
  • 如果接口主要用于特定用途,例如创建新的实现,请考虑将它们放在子命名空间(如Design或者ComponentModel)中。

我敢肯定还有其他选择,但是与大多数名称空间问题一样,它取决于项目的用例以及它所包含的类和接口。

(.Net)我倾向于将接口保留在单独的"通用"程序集中,因此我可以在多个应用程序中使用该接口,并且更经常地在我的应用程序的服务器组件中使用该接口。

关于名称空间,我将它们保留在BusinessCommon.Interfaces中。

我这样做是为了确保我和我的开发人员都不想直接引用这些实现。

以某种方式分离接口(Eclipse中的项目等),以便仅部署接口就很容易。这使我们无需提供实现即可提供外部API。这样,相关项目就可以以最少的外部量进行构建。显然,这更适用于较大的项目,但是在所有情况下该概念都是好的。

我更喜欢将接口和实现类保留在相同的名称空间中。如果可能,我会给实现类提供内部可见性,并提供一个工厂(通常以委托给worker类的静态工厂方法的形式提供),该内部方法允许在朋友程序集中的单元测试替换另一个产生存根)。当然,如果具体类需要是公共的,例如,如果它是一个抽象基类,那很好。我看不出有任何理由将ABC放在其自己的名称空间中。

附带一提,我强烈不喜欢.NET约定以字母" I"开头的接口名称。 (I)Foo接口模型不是ifoo,它只是一个foo。那么,为什么我不能只称呼它为Foo?然后,我专门命名实现类,例如AbstractFoo,MemoryOptimizedFoo,SimpleFoo,StubFoo等。

我通常将它们分成两个单独的程序集。接口的常见原因之一是使一系列对象在软件的某些子系统中看起来相同。例如,我有所有实现IReport接口的报告。 IReport不仅用于打印,还用于预览和选择每个报告的单个选项。最后,我有一个IReport集合,可在对话框中使用,在该对话框中,用户可以选择要打印的报告(和配置选项)。

报表驻留在单独的程序集中,而IReport,预览引擎,打印引擎,报表选择驻留在它们各自的核心程序集和/或者UI程序集中。

如果我们使用Factory类返回报告组合中的可用报告列表,则使用新报告更新软件仅是将新报告组合复制到原始报告中的问题。我们甚至可以使用Reflection API来仅扫描程序集列表中的任何报告工厂,并以此方式构建报告列表。

我们也可以将这种技术应用于"文件"。我自己的软件运行一台金属切割机,因此我们将此想法用于与软件一起出售的形状和配件库。

同样,实现核心接口的类应该驻留在单独的程序集中,因此我们可以与软件的其余部分分开进行更新。