假设我有一个"应用程序"类.为了初始化,它需要在构造函数中进行某些设置.我们还假设设置的数量太多,以至于将它们放在自己的类中是很有吸引力的.
比较此方案的以下两种实现方式.
实施1:
class Application { Application(ApplicationSettings settings) { //Do initialisation here } } class ApplicationSettings { //Settings related methods and properties here }
实施2:
class Application { Application(Application.Settings settings) { //Do initialisation here } class Settings { //Settings related methods and properties here } }
对我来说,第二种方法更为可取.它更具可读性,因为它强调了两个类之间的关系.当我编写代码以在任何地方实例化Application类时,第二种方法看起来更漂亮.
现在想象一下,Settings类本身又有一些类似的"相关"类,而该类反过来也是如此.只有三个这样的级别,类命名在'非嵌套'的情况下失控.然而,如果你筑巢,事物仍然保持优雅.
尽管如此,我还是读过人们在StackOverflow上说嵌套类只有在外部世界不可见时才被证明是合理的.也就是说,它们仅用于包含类的内部实现.通常引用的异议是包含类的源文件的大小膨胀,但是部分类是解决该问题的完美解决方案.
我的问题是,为什么我们对嵌套类的"公开暴露"使用持谨慎态度?还有其他反对这种用法的论据吗?
我认为没关系.这基本上是构建器模式,并且使用嵌套类非常有效.它还允许构建器访问外部类的私有成员,这非常有用.例如,您可以在构建器上使用Build方法,该方法在外部类上调用私有构造函数,该构造函数接受构建器的实例:
public class Outer { private Outer(Builder builder) { // Copy stuff } public class Builder { public Outer Build() { return new Outer(this); } } }
这确保了构建外部类的实例的唯一方法是通过构建器.
我在Protocol Buffers的C#端口使用了非常类似的模式.
您可以使用命名空间来关联相关的事物.
例如:
namespace Diner { public class Sandwich { public Sandwich(Filling filling) { } } public class Filling { } }
与使用类名称空间一样使用类的优点是,您可以选择using
在调用端使用缩写:
using Diner; ... var sandwich = new Sandwich(new Filling());
如果您将该Sandwich
类用作名称空间Filling
,则必须使用全名Sandwich.Filling
来引用Filling
.
那你知道那晚怎么睡觉?