SOLID原则真的很扎实吗?

Ars*_*eny 39 .net c# design-patterns solid-principles

这个缩写词中第一个字母的设计模式是单一责任原则.这是一个引用:

单一责任原则规定每个对象应该承担单一责任,并且该责任应该由班级完全封装.

在我们开始编码之前,这很简单明了.假设我们有一个具有明确定义的单一责任的类.要序列化类实例,我们需要为该类添加特殊的属性.所以现在班上有另一个责任.这不违反SRP吗?

让我们看另一个例子 - 接口实现.当我们实现接口时,我们只需添加其他职责,比如处理其资源或比较其实例或其他任何内容.

所以我的问题.是否有可能严格遵守SRP?怎么做到呢?

小智 70

正如您将来发现的那样,软件开发中最着名的原则都不能100%遵循.

编程通常是关于妥协 - 抽象的纯粹性与代码大小与速度与效率的关系.

你只需要学会找到合适的平衡:不要让你的应用程序陷入混乱的深渊,而不是将自己的手与多个抽象层绑在一起.

  • 同意在不理解规则的情况下试图遵守规则是一个很大的错误.规则有原因,当您的上下文不符合这些原因时,您必然会有例外. (9认同)

Ste*_*dit 13

我不认为可序列化或一次性可以承担多重责任.

  • 同意.SRP是SOLID原则中最"坚实"的,IMO.其他人可能会偶尔弯腰,但不应该违反SRP. (8认同)
  • +1 - 添加属性不会增加责任 (8认同)
  • @Developer Art:我想说添加一个接口或属性*会改变类,但它不一定*改变它的*责任*.这一切都取决于添加的内容.例如,IDis可以是GC管道问题,而不是功能.另一方面,如果User类突然实现IEnumerable <Anteaters>,那将违反SRP(和常识). (3认同)
  • @Stephen:我认为这里的诀窍是了解什么构成单一责任.在实践中,这将取决于课程的预期,以及"玩得好"所需的内容. (2认同)

Rob*_*boy 10

我想首先要注意的是,这些只是良好的软件工程原则 - 您还必须应用判断.所以从那个意义上说 - 不是他们不坚固(!)

我认为你提出的问题提出了关键点 - 你如何定义班级应该具有的单一责任?

重要的是,在定义责任时不要过于沉迷于细节 - 仅仅因为一个类在代码中做了很多事情并不意味着它有很多响应.

但是,请坚持下去.尽管在所有情况下都可能无法应用 - 但它仍然比在代码中使用单个"God Object"(反模式)更好.

如果您遇到这些问题,我建议您阅读以下内容:

  • 重构 - Martin Fowler:虽然这显然是关于重构,但本书在展示如何将问题分解为逻辑部分或可靠性方面也非常有用 - 这对SRP至关重要.这本书也涉及其他原则 - 然而它的学术方式比你以前看到的要少得多.

  • 清洁代码 - 罗伯特马丁:谁比SOLID原则的最大指数更好阅读.说真的,我发现这对软件工艺的所有领域都是一本非常有用的书 - 而不仅仅是SOLID原则.就像福勒的书一样,这本书适用于所有级别的经验,因此我会推荐给任何人.

  • 清洁代码是我正在阅读的那本书,当我终于让OO/Testable代码灯亮起时.本书最好的部分是使用前/后样本清理代码.真正令我印象深刻的是视觉上我们的代码*看起来像以前那样多少,它真的帮助我理解为了理智而将代码移动的方向 (5认同)

STW*_*STW 8

为了更好地理解SOLID原则,您必须了解它们解决的问题:

面向对象的编程源于结构化/程序化编程 - 它增加了一个新的组织系统(类,等)以及行为(多态,继承,组合).这意味着OO不是从结构化/程序化中分离出来的,而是一个进步,如果他们想要,开发人员可以做非常程序化的OO.

所以... SOLID作为一个试金石来回答"我真的在做OO,还是我只是使用程序对象?"的问题.如果遵循5条原则,则意味着您在光谱的OO方面相当远.不符合这些规则并不意味着你没有做OO,但它意味着它更多的结构/程序OO.

  • 或者,换句话说,你没有利用OO.这很糟糕,不是中立的. (3认同)

Dan*_*ant 5

这里有一个合理的问题,因为这些横切关注点(序列化,日志记录,数据绑定通知等)最终会将实现添加到多个类中,这些类只支持其他子系统.必须对此实现进行测试,因此该类肯定承担了额外的责任.

面向方面编程是一种尝试解决此问题的方法.C#中的一个很好的例子是序列化,对于不同类型的序列化,存在各种不同的属性.这里的想法是类不应该实现执行序列化的代码,而是声明它是如何序列化的.元数据是一个非常自然的地方,包含对其他子系统很重要的细节,但与类的可测试实现无关.