【问题标题】:Using the Single Responsibility Principle in the "real world" [closed]在“现实世界”中使用单一职责原则 [关闭]
【发布时间】:2009-01-28 18:05:41
【问题描述】:

我基本上想了解认为在实际代码中使用单一职责原则是合理的人的百分比以及实际使用的人数。在Podcast #38 Joel 谈到这个 OOP 原则在现实世界中是多么无用;并进一步表明,像鲍勃叔叔这样的人可能没有编写过非平凡的系统。

我亲自编写过一些软件项目或在其中发挥了重要作用,但在我年轻的职业生涯中直到现在才遇到这种模式。我喜欢这个原则的声音,并且真的很想开始使用它。我发现 Joel 在播客中的论点很弱(如果您继续阅读博客 cmets here,其他人也是如此)。但是,这其中有什么真相吗?

社区怎么看?

【问题讨论】:

  • 我认为你应该把它变成一个维基,因为没有一个明确的答案。
  • 我不确定我是否同意。我认为他们的正确答案越来越少。而且我认为有太多人认为这比实际情况更加主观或上下文敏感——这也是我发布这个问题的部分原因。不过感谢您的评论。

标签: oop solid-principles single-responsibility-principle


【解决方案1】:

我有一些应用SOLID 原则的经验,我的经验主要是好的。我也听过播客,听起来 Jeff 和 Joel 都没有尝试过他们谈论的任何事情,时间足够长,无法真正评估其好处。反对的主要论据通常是“您编写更多代码”。如果我看一下我所做的事情,我会多写 10 可能 20% 的代码(通常是接口定义),但是因为一切都是高度解耦的,所以它更易于维护。我几乎从来没有遇到过应用程序某个部分的更改会破坏其他部分的情况。所以我必须维护的 20% 的额外代码是自己付出的。

Jeff 也错过了代码质量这一点。他不认为代码质量对客户有很大好处。他是对的,客户不在乎。客户确实关心快速实施新功能,这就是代码质量的用武之地。我发现,保持尽可能高的代码质量的投资总是在几个月内收回成本。高品质 = 低维护。

我同意他们的观点,喜欢任何事情你必须对这些事情务实。如果您需要交付某些东西,那么请继续快速而肮脏地完成它。但事后清理。

【讨论】:

    【解决方案2】:

    我正在开发一个项目,该项目在一个应该可以被其他人轻松扩展的框架中完成许多不同的、极其复杂的事情。

    起初,班级很大,做的事情很多。为了改变这些行为,您必须扩展这些类。这些方法都是虚拟的,不会改变对象的状态,所以很容易做到。

    但是随着系统的发展,框架最终将包含一系列单体对象变得越来越清楚,每个对象都有很长的继承链。这也导致了意外的依赖关系——一个抽象方法采用类 X 的集合来生成在基类中定义的对象 Y,这要求每个人都必须这样做,即使它对继承树的一半没有意义。这也导致了需要数十个单元测试才能使代码覆盖率超过 80% 的大量类,而且复杂性如此之大,以至于您不确定是否正确覆盖了所有内容。很明显,这种设计会导致框架非常僵化和不灵活。

    因此,我们按照 SRP 线重新设计了所有内容。您将拥有您的接口、一个基类,并且可能还有一个或多个实现类。每一个都不同的对象组成,这些对象执行整个过程的关键功能。如果你想改变一个部分,你没有重写一个方法,你会产生另一个对象来扩展必要的接口/基类并以不同的方式执行它的工作。 SRP 甚至被纳入类方法的参数和返回值中。对于那些需要灵活的系统部分,而不是传递用于生成 Y 对象的 X 类的集合,创建了一个类来封装 Y 对象的生成过程。然后系统中的组件将传递这些生产者,将它们与其他生产者组合(生产者的责任),并最终使用它们来生产 Y。这允许创建不同类型的生产者,所有这些都可以完全按照相同,即使他们做了截然不同的事情。此举还大大减少了每个类的代码库,并使它们更容易测试。

    我想说,作为一个新开发者,将所有内容分解到这个级别是非常困难的。您几乎必须编写一大堆泥巴,了解它的工作原理,然后将其重新设计为几个不同的组件,每个组件负责整体的一部分。

    【讨论】:

      【解决方案3】:

      我没有读过或听过 Joel 的 cmets,所以无法具体评论。

      我认为你必须从目标的角度来看待单一责任原则,而不是严格的要求。与软件开发中的许多事情一样,应该为理想而奋斗,但除非您的代码没有金钱收益或成本,否则您必须务实地满足客户的需求。

      【讨论】:

      • 我怀疑是否有任何客户关心开发人员纪律和 OO 原则的执行,但是必须维护/使用代码的您(或其他任何人)可能会喜欢它。
      • 我不反对。只是有时实用主义胜过严格执行这一特定原则。
      【解决方案4】:

      在实践中,在 OO 情况下很难获得真正的 SRP。考虑一个存在于复杂系统中的类。它可能只有一项面向业务的职责(例如打印报告),但它在内部还有许多其他违反纯 SRP 理念的职责,例如日志记录和异常处理。如果您显着更改日志记录机制,您可能需要更改打印类的调用。

      这就是构想 AOP 的原因。使用它,您无需更改任何内容,只需更改日志记录类即可更改日志记录。

      出于显而易见的原因,争取面向业务的 SRP 是件好事,但对于足够复杂的系统,您将永远无法在 OOP 中获得真正的 SRP。 AOP,当然,但不是 OOP。

      我不知道乔尔是不是这么想的,但我就是这样处理这个想法的。

      【讨论】:

        【解决方案5】:

        现有大量编程理论中的一些最大的问题是,它们专注于建议代码中的良好属性,实际上是代码的良好属性。它们是正确的,因为它们本质上是正确的,因此并不是特别有用。

        是的,代码应该写得很好,是的,事情不应该可怕地重复,是的,更改不应该在意想不到的地方造成奇怪的中断。但是,归根结底,以简单易懂的方式表达解决方案的真正简单、真正一致的代码远比满足某些严格原则的大型复杂系统更有价值。作为一个行业,我们倾向于将好想法做得太过分,在寻求“正确”解决方案而不是最佳解决方案时造成大量不必要的复杂性。

        保罗。

        【讨论】:

          【解决方案6】:

          我认为,成为一名纪律严明的 OO 开发人员并尽可能遵守 SRP 的最大好处是易于测试和维护,因此我认为 SRP 对于任何要进行测试/维护的系统来说都是一个很好的目标(基本上,除了一次性系统之外的任何东西)。

          【讨论】:

            【解决方案7】:

            我认为 SOLID 原则有时不符合设计类时通常应用的自然/业务逻辑。 Robert C. Martin 举了一个 Rectange 和 Square 类的例子(Square 不应该是 Rectangle 的后代)。

            http://www.hanselminutes.com/default.aspx?showID=163

            我不确定它是否与 SRP 有关,但想法是一样的。 SOLID 原则可能会导致违反直觉的决定,而且很难跨越这个障碍。

            对我来说,“准则”比“原则”更合适。

            【讨论】:

              【解决方案8】:

              总的来说,我同意 SOLID 原则,但您也必须将它们纳入上下文。如果您正在编写概念证明,那么 SOLID 原则就不那么适用了。

              另一方面,如果您要开发的产品的使用寿命将跨越数年,那么您最好仔细研究 SOLID 原则并加以应用。否则,它将在生产力方面花费公司大量资金。

              关于 Joel 和他的 cmets,他有一个正确的观点。有时产品需要发货或公司倒闭。就是那样子。

              作为开发人员,交付产品是您的工作,但截止日期紧迫并不意味着您采用糟糕的架构。选择使用数据集还是业务实体是一个简单的决定,两者都有相似的实施工作,但从长远来看,两者之间的新功能开发和维护是激烈的。

              【讨论】:

                【解决方案9】:

                我认为应该可以为所有类编写一个简单的一行主要职责。这个单行中的“和”这个词通常不是一个好兆头。然后,单一职责通常归结为选择适当的抽象。

                GUI 附近的类倾向于反映 GUI,并具有“为 XXXX 做 gui”的单一职责。懦夫的解决方案..

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-05-24
                  • 2019-11-15
                  • 2016-01-21
                  相关资源
                  最近更新 更多