code-duplication - 根据 Robert C. Martin 的代码复制和 SRT
问题描述
我正在阅读 Robert C. Martin 的 Clean Architecture 书。在单一职责原则的示例中,他演示了一个具有三个公共方法的 Employee 接口calculatePay
:reportHours
和saveEmployee
:
class Employee {
public:
float calculatePay();
float reportHours();
void saveEmployee();
private:
float calculateRegularHours();
}
他认为这三种方法不应包含在同一类中,因为它们服务于不同的参与者:首席财务官、首席运营官和首席技术官。然后他描述了后果:如果 CFO 决定更改计算正常工作时间的方法,那么程序员可能会意外更改 COO 的计算算法,因为他们依赖于相同的方法 calculateRegularHours。
我的问题是:遵守 SRP 对我们有什么帮助?即使我们在两个不同的类中实现calculatePay
,reportHours
它们仍然依赖于同一个方法calculateRegularHours
,所以要么我们实现这个方法两次(这将是代码重复),要么我们必须接受对其进行更改会影响两个参与者的风险。
哪一点我没看到?您将如何处理这种特殊情况?
谢谢您的回复!
解决方案
要么我们实现这个方法两次(这将是代码重复)
它看起来像代码重复,但事实并非如此。calculateRegularHours
事实上,它的实现calculatePay
和reportHours
使用是相同的,这只是一个意外。
由于calculatePay
和reportHours
服务于不同的演员,他们会在不同的时间因不同的原因而改变。因此,这些参与者中的一个很可能会请求另一个参与者不想要的更改。那么当涉及到这个请求时,你会怎么做呢?我猜你会将calculateRegularHours
逻辑分成两个实现。一个用于calculatePay
,一个用于reportHours
。但也有可能您忘记了它,并且您将在与您想要进行的更改无关的地方破坏系统。这使系统变得脆弱。
Robert C. Martin 在此视频(39:26 - 43:00) 中对此进行了解释。
我想 SRP 违规的一个更好的例子是将服务 UI 的方法放在业务对象中,甚至将 SQL 放在视图中。
无论你做什么,你都应该进行测试,因为测试可以告诉你你在一个完整的其他领域破坏了系统。如果发生这种情况,您应该重新考虑设计并记住 SRP。
推荐阅读
- javascript - 如何在 WebGL 中创建矢量画笔工具?(如 Clip Studio 或 Concepts)
- angularjs - Angularjs上传多个文件
- snowflake-cloud-data-platform - 来自 s3 的雪花副本,带有 jdbc 但没有加载状态
- github - 如何将插件从 Github 存储库迁移到 Odoo.sh
- excel - 我想搜索每个工作表中的每一行以查找文本,然后返回整行数据
- python - Python中function.boolean = True的目的是什么
- html - 没有 JavaScript 的自动刷新 IMG 标记?这是如何工作的?
- c++ - 构建具有工厂功能的不可移动底座
- spring-boot - ChainedTransactionManager 在不同的线程中调用 AfterCompletion
- c++ - 如何使用头文件声明在另一个 cpp 文件中定义的函数以在我的主文件中使用?