.NET:在文件之间划分命名空间的最佳实践/指南是什么?

13
将应用程序代码(App_Code)分成单独的文件应该遵循哪些通用准则?随着命名空间层次结构的演变,我发现难以与原始文件相匹配。如何使应用程序代码容器在时间上保持直观组织?文件的分割应该达到什么目的?是代码可移植性?还是关注点分离?还是一般的功能上下文?还是频繁更改的频率?它们应该力争实现类的一对一关系吗?将代码分割成许多小文件与合并成少量文件有什么影响?我经常思考这个问题,但从未达到适用于所有情况的一般结论。
5个回答

13
这个问题的答案不是绝对的,它通常取决于你手头的任务。如果你正在创建一些供他人重复使用的SDK,则命名空间非常重要;然而,如果你只是创建一个有几个类的内部工具,则命名空间几乎没有什么重要性。
通常来说,每个类应该有自己的文件,这样简化了人们对代码解决方案的导航,有助于开发和维护(例如,当每个人都在更改同一个文件时,合并更改变得更加困难)。在某些情况下,将一个类分成多个文件可能是可以接受的,例如:
当存在嵌套类时,每个嵌套类都可以有自己的文件。
当存在自动生成的部分时,比如设计师代码。
当存在固定部分时,例如一组隐藏属性或接口的公共实现。
在我们的某个项目中,许多类都公开了接口的公共实现。由于我们没有多重继承,我们采用了混入方法,通过为每个类自动生成附加文件来实现。这也可以手动完成,而不是自动完成(最初就是这样做的)。
还有其他情况,但这在某种程度上是主观的,并取决于您自己项目的要求。
命名空间通常应专注于类型的合理分组。命名空间应该允许开发人员直观地找到他们正在寻找的东西。对于许多小型项目,一个单一的命名空间,例如MyAwesomeTool就足够了,但是对于许多类的较大项目来说,需要更合理的分组。像SDK或.NET BCL这样的大型项目依靠命名空间来分解否则会让人感到压倒性的大量类型。每个命名空间级别提供了有关可能在其中找到的内容的其他信息,例如System.Windows.FormsSystem.DrawingMicrosoft.VisualBasic。创建命名空间时,必须考虑该命名空间及相关项目的目的。如果项目是内部小型项目,则可以自己随意命名命名空间,因为它只是将类型分组的必要性;如果项目对外可见或包含大量类型,则应仔细考虑逻辑和有意义的分组方式,以便使他人能够直观地找到他们所需的类型。
结论:没有适用于所有情况的硬性规则。如何将代码排列到文件中涉及到您自己的开发流程,影响您和您的团队;将所有类放在一个文件中进行开发将很难,但编译后的产品不会有任何不同(前提是一次性文件方法不会导致错误),而将命名空间排列起来则涉及到未来的开发和这些命名空间的使用者,因此,搞错后果可能更为严重。
建议:旨在以简化当前开发和未来维护的方式组织您的类。旨在以简化所有开发和(在适当的情况下)最终用户体验的方式组织您的命名空间。

命名空间对于任何不是小型单人项目的东西都至关重要。随着项目的发展,你会不断被问到:我应该把这个放在哪里。如果没有清晰的指导,你将浪费大量时间来尝试放置和查找东西,然后当你意识到你的方案没有意义时重新组织。 - Quark Soup

6

类和源文件之间应该存在一对一的映射关系。

命名空间应该被视为一个可以包含一个或多个类的包。如果可能的话,将其表示为Visual Studio项目窗口中的文件夹/筛选器可能是有用的。

如果您发现一个庞大的类会受益于拆分成单独的文件,则应考虑重构和拆分类本身,而不是拆分文件。

唯一的(可接受的)例外是生成UI的代码,Visual Studio 将其放在一个单独的文件中。我建议将其保留在自己的文件中,并尽可能地将其视为透明的编辑器所有文件。


4

大多数建议都是让每个公共类型都应该放在自己的文件中,而命名空间则应该代表应用程序的文件夹结构。


我不确定在命名空间中复制文件夹结构是否真的有任何实际好处。 命名空间的目的基本上是防止命名冲突。 我倾向于采用我所谓的“命名空间奥卡姆剃刀原则”-它们不应该不必要地扩散。 - Tim Long

1

我通常会将99%的1对1类放在一个文件中。唯一的例外是如果您有大量或非常简单的小类,这些类都实现相同的接口并且不应该经常更改。您可能希望将它们放在一个文件中。自定义异常可以作为一个很好的例子。大多数情况下(根据我的经验),除了创建自定义消息或类似的内容之外,没有其他代码。

命名空间应该首先按照关注点分离进行组织。例如,数据对象应该与域对象位于不同的命名空间中。然后,您可以在“聚合根”级别为每个对象组拥有一个较小的子域。通常,这些最小的命名空间对应其自己的项目和DLL。


1
就类而言,我倾向于遵循Java规则:“每个文件一个公共类”。如果该公共类是唯一的用户,则可以将私有类与公共类放在一起。(虽然,枚举类型正在减少这种情况); 但是,如果它被同一命名空间中的多个公共类使用,则将其放在其自己的文件中。
我通常会使用以下命名空间:

MyAwesomeApp.UI
MyAwesomeApp.Business
MyAwesomeApp.Data

为了反映层之间的分离。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接