2

为了将我的编程技能和习惯带入 21 世纪(从 Pascal 和 Fortran 迁移到 C# 和 C++),我自主努力,一直在研究大量可用的源代码。据我所知,类是唯一的“独立”实体(很像它们的 Function 祖先)。

但是,我遇到过许多实例,其中一个或多个类嵌套在另一个类中。在这方面,我的“直觉”是,这样做仅仅是因为方法论极差——但是,我对现代 OOP 方法论还不够熟悉,无法真正做出这样的决定。

因此,以下重叠的问题:

将一个类嵌套在另一个类中是否有合理的理由?而且,如果是这样,与每个类别完全独立相反,这样做的理由是什么?

(注意:我看到的示例一直使用 C#,但似乎这方面同样适用于 C++。)

4

4 回答 4

3

嗯,这可能需要一个非常有启发性的答案,因此很多人会不同意我的答案。我是那些认为没有真正需要嵌套类的人之一,我倾向于同意你的说法:

在这方面,我的“直觉”是这样做仅仅是由于方法极差

人们觉得需要设计嵌套类的情况是功能与外部类中设计的行为紧密耦合的情况。例如,事件处理可以设计在内部类中,或者Threading行为可以找到内部类的方式。

我宁愿从“外部”类中重构特定行为,以便最终得到两个具有明确职责的较小类。

对我来说,设计内部类的主要缺点是它们倾向于使功能变得混乱,这很难(更)与原则一起用作TDD(测试驱动开发)。

如果您不依赖测试驱动的主体,我认为它不会对您造成太大伤害。这(就像很多事情一样)是品味问题,而不是对与错的问题。我了解到,这个话题可能会导致冗长而令人筋疲力尽的讨论。非常类似于您是否应该使用static辅助类,这些辅助类往往不仅仅是“成为帮助者”,并且随着时间的推移越来越多的状态。

如果你遇到一个现实生活中的例子,讨论会变得更加具体。在那之前,它主要是人们的“直觉”。

于 2013-03-03T20:15:23.043 回答
1

C# 中嵌套类的常见用途包括供类内部使用的类,您不希望在模块的内部命名空间中公开这些类。例如,您可能需要抛出一个不向外界公开的异常。在这种情况下,您可能希望将其设为嵌套类,以便其他人无法使用它。

另一个例子是二叉树的Node类。它不仅是您不希望在课堂之外公开的东西,而且它可能需要访问私有成员以进行内部操作。

于 2013-03-03T20:55:07.513 回答
0

您经常遇到嵌套类的一个领域(尽管可能没有注意到)是枚举器(即实现的类IEnumerator<T>)。

为了让一个集合支持多个同时枚举(例如在多个线程上,或者甚至只是foreach在同一个集合上的嵌套循环),枚举逻辑需要从集合中分离到另一个类中。

但是,枚举器通常需要了解集合的实现细节才能正常工作。如果您要使用完全独立的(非嵌套)类来执行此操作,则必须使这些内部结构比它们真正应该的更易于访问,从而破坏封装。(有人可能会争辩说它可以使用internal成员来完成,但我认为这仍然在某种程度上破坏了封装,即使它“只是”将实现细节暴露给同一程序集的成员)。

通过为枚举器使用私有嵌套类,这些问题在保持适当封装的同时消失了,因为嵌套类可以访问其包含类的内部。

于 2013-03-03T20:45:54.377 回答
0

嵌套类有利有弊。专业人士以有意使用为中心,例如IEnumerator<T>提到的 Iridium 和嵌套类以促进WPF/MVVM中的命令模式。SQL 创建、读取、更新和删除 (CRUD) 操作很流行,用于将这些模式封装在代码中的类/命令中,用于业务线/数据驱动的应用程序。

与嵌套类相关的负面因素与调试相关 - 嵌套的类越多,复杂性就越高,越容易引入错误,调试它就越难。即使使用命令模式之类的东西,按照它的组织方式,也会因为太多的类/命令而使你的类膨胀。

于 2013-03-03T21:47:07.813 回答