首页 > 解决方案 > 根据 Robert C. Martin 的代码复制和 SRT

问题描述

我正在阅读 Robert C. Martin 的 Clean Architecture 书。在单一职责原则的示例中,他演示了一个具有三个公共方法的 Employee 接口calculatePayreportHourssaveEmployee

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

private:
  float calculateRegularHours();
}

他认为这三种方法不应包含在同一类中,因为它们服务于不同的参与者:首席财务官、首席运营官和首席技术官。然后他描述了后果:如果 CFO 决定更改计算正常工作时间的方法,那么程序员可能会意外更改 COO 的计算算法,因为他们依赖于相同的方法 calculateRegularHours。

我的问题是:遵守 SRP 对我们有什么帮助?即使我们在两个不同的类中实现calculatePayreportHours它们仍然依赖于同一个方法calculateRegularHours,所以要么我们实现这个方法两次(这将是代码重复),要么我们必须接受对其进行更改会影响两个参与者的风险。

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

谢谢您的回复!

标签: code-duplicationsingle-responsibility-principleclean-architecture

解决方案


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

它看起来像代码重复,但事实并非如此。calculateRegularHours事实上,它的实现calculatePayreportHours使用是相同的,这只是一个意外。

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

Robert C. Martin 在此视频(39:26 - 43:00) 中对此进行了解释。

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

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


推荐阅读