Robert C. Martin的代码复制和SRT

时间:2019-07-06 09:18:19

标签: code-duplication single-responsibility-principle clean-architecture

我正在阅读Robert C. Martin的《清洁建筑》一书。在“单一职责原则”的示例中,他演示了一个具有以下三种公共方法的雇员接口:calculatePayreportHourssaveEmployee

class Employee {
public:
  float calculatePay();
  float reportHours();
  void saveEmployee();

private:
  float calculateRegularHours();
}

他认为这三种方法不应包含在同一类中,因为它们服务于不同的角色:首席财务官,首席运营官和首席技术官。然后,他描述了后果:如果CFO决定更改定期工作时间的计算方法,则可能会偶然发生程序员意外更改COO的计算算法的情况,因为他们依赖于相同的方法validateRegularHours。

我的问题是:遵守SRP对我们有何帮助?即使我们在两个不同的类中实现了calculatePayreportHours,它们仍将依赖于相同的方法calculateRegularHours,因此我们要么两次实现此方法(这将是代码重复),要么必须承担改变的风险会影响两个参与者的风险。

我看不到哪一点?您将如何处理这种特殊情况?

感谢您的答复!

1 个答案:

答案 0 :(得分:0)

  

要么我们两次实现了此方法(这将是代码重复)

它看起来像代码重复,但不是。 calculateRegularHourscalculatePay使用的reportHours的实现是相同的,这只是偶然。

由于calculatePayreportHours服务于不同的参与者,因此它们将在不同的时间因不同的原因而变化。因此,这些参与者之一可能会请求其他参与者不希望的更改。因此,当涉及到此请求时,您会怎么做?我猜您会将calculateRegularHours逻辑分为2个实现。一个用于calculatePay,另一个用于reportHours。但是也有可能您忘记了它,并且会在与您要进行的更改无关的地方破坏系统。这会使系统变得脆弱。

罗伯特·C·马丁(Robert C. Martin)在this video中进行了解释(39:26-43:00)。

我认为违反SRP的一个更好的例子是将为UI提供服务的方法放在业务对象中,甚至将SQL放在视图中。

无论您做什么,都应该进行测试,因为这些测试可以表明您在其他完整区域破坏了系统。如果发生这种情况,您应该重新考虑设计并记住SRP。