嵌套类是否被低估?


9

我并不是要说我知道其他人都不知道的东西,但是我一直在使用嵌套类来解决越来越多的设计问题,所以我很好奇这种使用似乎很少使用的可接受性的感觉设计机制。

这就引出了一个问题:我是因为某种原因而走上了一条固有的糟糕道路,当他们再次咬我时会发现它们的原因,还是嵌套类可能被低估了?

这是我仅将其用于以下两个示例:https : //gist.github.com/3975581-第一个示例帮助我将紧密相关的继承体系保持在一起,第二个示例使我可以向受保护的成员提供访问权限...


我只想说谢谢您的答案/见解-我不确定如何选择答案,所以我会
仔细

Answers:


6

我不会将其称为“很少使用的设计机制”-至少不是通用的:尽管在有些商店中,有些贡献者可能不喜欢使用嵌套类,但这根本不是一个晦涩的功能。

尽管存在具有汇编可见性的类以及引入lambda大大减少了对嵌套类*的需求,但它们仍然是有效的设计选择。尽管名称空间中的内部类有些重叠,但是嵌套类功能是独特的,它使您可以将一个类完全隐藏在另一个类中。


*在Java中使用类似功能要高得多,因为Java中没有C#中可用的其他替代方法。


那么按照OOP设计的本质将一个类完全隐藏在另一个类中是否很好?
Maxood

1
@Maxood如果可以隐藏一个类,最好将其隐藏。API的用户应该对API的实现方式了解得最少。
dasblinkenlight

3

考虑一下,您正在另一个类中编写一个类,该类将永远不会在程序的其他任何地方使用。因为如果您在其他地方使用它,则将其设为普通的公共类,就像其他所有类一样。

因此,这里没有应该使OOP变得更好(可重用)的东西。此外,使用嵌套类可以实现什么,而使用父类中的普通方法和私有成员则无法实现?

有关利用嵌套类的有用软件模式,参见此处


10
我从来没有买过可重用性的东西,至少不是平时所说的。(1)调用现有的代码/类(您似乎在谈论,我通常将其视为重用的定义)与OOP完全无关,它只是基本的模块化。(2)子类型多态性是OOP的定义特征之一,它通过使特定的实现无关紧要从而允许重用客户端代码,即,无论具体类是否可访问,它的工作方式都完全相同。我购买的IOW可以重用,但它也适用于嵌套类。

1
我要说的是,父类还提供了名称空间隔离-因此,如果您愿意,类A和B都可以嵌套“ Params”类,并且可以访问包含类的非公共成员。难道它们都不都是在类之外使用内部类的原因吗?
亚伦·奥诺德

@AaronAnodide这应该是有关使用嵌套类的好方法的答案。正是我使用它们的方式/原因,它有助于组织代码。
Izkata 2012年

2

am I going down an inherintly bad path

我认为在您的第二个示例(工人子类)中,您肯定是。您已将每个子类映射到超类中的特定状态。因此,现在每次您要将状态添加到超类时,都需要在三个位置进行更改(将状态添加到超类,添加新的子类,并更改派生类的构造函数以将子类添加到列表中)。

使用嵌套类访问私有成员确实是一种有效的用法(我从未亲自这样做),但是您的特定情况在这里不起作用。

至于身体部位的例子。因为所有嵌套类都是公共的,所以除了命名空间之外,您实际上并没有做太多事情。如果这些类成长为包含更多功能,则您可能会发现嵌套类只会使接口混乱,并且正在筛选代码以查找特定的内容。我还注意到,因为您有嵌套的类,所以您不得不打破命名约定,并用小写字母命名类(也许这是一个选择)。但是这些论点比任何实际错误都更肤浅。

除非,当然,除非您需要实施一个不具体的手臂。然后执行以下操作来创建手臂会造成混乱,因为没有身体/躯干/侧面。(另请注意混乱的外壳)。

arm newArm = new Body.torso.side.arm("");

1

我能想到的嵌套类的唯一优点是可以将它们设置为私有(或受保护)。我想说,在这种情况下,如果一个类打算供外部类使用,并且该类单独使用,则嵌套类可以帮助您封装功能。


1

以我的经验,嵌套类

  • 回来困扰我
  • 我想偷工减料的时候就用过
  • 做一场噩梦
  • 对关注点分离和总体设计产生负面影响

对您的课程进行了简短的了解,我认为:

  • 看着它很痛苦,因为班级很多
  • 我不能在几乎没有创造整个身体的情况下测试“手指”
  • 我不能有多种躯干实现方式。在“人体”环境中似乎并不那么明显,但是在不同的情况下,这将变得显而易见。

为什么不将您的类分为多个类,并为它们提供单独的名称空间。例如

WindowsGame1.PhysicalModel.UpperBody
WindowsGame1.PhysicalModel.LowerBody
WindowsGame1.PhysicalModel.UpperBody.Arms
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.