封装何时胜过 SOLID - public vs private c# 类?
Posted
技术标签:
【中文标题】封装何时胜过 SOLID - public vs private c# 类?【英文标题】:When does encapsulation trump SOLID - public vs private c# class? 【发布时间】:2012-09-19 05:10:02 【问题描述】:我正在处理一些从其中一个示例派生的 MonoTouch 代码(这不是 MonoTouch 特定问题),并且示例代码在另一个类中声明了一个私有类。我还没有看到在 c# 中大量使用私有类,我不知道它什么时候才有意义。我可以看到一个只在另一个类中引用的类是如何被声明为私有的,但这不会导致比它的价值更多的悲痛吗?这不会违反一些 SOLID 原则吗?
单一职责 - 损坏? 打开/关闭 - 损坏? Liskoff 替换 - 也许可以? 接口隔离 - 损坏? 依赖倒置 - 损坏?现在,由于私有类的定义,我发现仅仅试图导航源代码会让人感到困惑。我想这可以通过声明一个包含私有类的部分类并将它们分成单独的文件来缓解,但这真的是一个好方法吗?
【问题讨论】:
标准答案,视情况而定。显然,这非常依赖于嵌入式类用于实现什么。如果嵌入类可以独立于封闭类进行更改,那么这不是违反 SRP 吗? 嵌入式类不(不能)对外界承担任何责任。它是微宇宙的一部分,它有自己的(可能是单一的)责任。 @HenkHolterman:这正是我的想法,它不能,至少不应该(如果你想遵循原则),有任何它的封闭类型之外的责任。我认为有人会决定将它放在那里并首先将其设为私有。 【参考方案1】:通常,嵌套类型(类或结构,包括枚举)用于某种上下文数据和/或行为,没有上下文就没有任何意义。
例如,您可以为某些互操作 API 创建嵌套类型,当您不想从外部代码提供对该 API 的访问时,或者您正在使用某种帮助数据容器,它提供功能,仅对周边班级。
因此,即使将这些类型设为internal
也会给其他开发人员带来混乱(尤其是在多个人编辑单个项目的情况下)。
我不明白,这里的 SOLID 是如何被破坏的 - 嵌套类型只是类型范围的限制。它不是周边类的功能扩展。
【讨论】:
谢谢丹尼斯。我得到的印象是我正在查看的代码不恰当地使用了 private 类。仅仅因为嵌入类只被封闭类使用并不足以成为嵌入它的理由。【参考方案2】:在 API 说“当我们要求您提供此接口的实现并向我们提供该接口的实现”的情况下,我使用了私有类,并且该类除了使用之外没有其他用途或消费者API 接口。
在这种情况下,接口提供公共或跨功能访问,因此无需访问实现。
【讨论】:
好的,我可以看到它有一些优点。你如何测试你的私人课程? 我编写单元测试请求接口,并练习接口。 对,这是有道理的。 IIUC,public 封闭类型是门面类型吗?您是否有一个实现接口的 public 方法,然后使用 private 类上的方法来实现功能?你能举个例子吗?这不是我在我正在使用的示例中看到的用法。在示例代码中,private 类用于嵌入由封闭类型使用的类型。【参考方案3】:为什么会破坏 SRP?您将只能在类内部访问的职责分离到嵌套类中。
大多数其他原则不适用于私有成员或私有嵌套类。
【讨论】:
为什么其他原则突然不适用于私有嵌套类?当然,私有类根据定义与封闭类强耦合,这是 SRP 试图解决的问题之一。 私有类不是用户可以直接使用或扩展的东西。私有方法也可以与类紧密耦合,但这是设计使然,不应该是扩展点或可重用算法。 用户在什么情况下?我不是在构建库或框架。我是应用程序中代码的生产者和消费者,那么为什么不将我的所有类都设为私有呢?而且我不相信耦合与方法有关。公共或私有,方法与类耦合,方法不能存在于类之外。 有些东西是没有状态的静态方法。但严肃地说,私有嵌套类可能也不可能单独存在,因为它对外部类私有成员有深入的了解。是否将逻辑封装到方法或类中的问题取决于您。 一个诡计多端的问题是嵌套的公共类。它可能是一个构建器类,它通过多个步骤(方法调用)构建外部类,并且需要了解私有变量。在这种情况下,它有助于不违反 SRP,否则外部类将负责构建自己。在 .NET 中,您可以在同一程序集中使用构建器类,并在“外部”类上使用内部方法/属性,但耦合仍然存在。在 Java 代码中,像“DialogBox.createBuilder().build()”这样的代码比较常见,并且使用嵌套类。【参考方案4】:我不确定,但我认为单一职责可以被嵌套类打破,因为一个类现在可以有更多的理由来改变。 Single Resposibilty 的定义不是很清楚......无论如何,我认为 ms 确实在 .net 中也使用了嵌套类,所以也许 c# 在封装方面缺少一些功能。我认为嵌套类可以通过不做嵌套类和编写分析器来修复。嵌套类通常用于访问包装类的私有成员。
【讨论】:
以上是关于封装何时胜过 SOLID - public vs private c# 类?的主要内容,如果未能解决你的问题,请参考以下文章
asp.net core系列 65 正反案例介绍SOLID原则
Hadoop MapReduce vs MPI(vs Spark vs Mahout vs Mesos) - 何时使用一个而不是另一个?