我正在阅读Robert C. Martin的《清洁建筑》一书。在“单一职责原则”的示例中,他演示了一个具有以下三种公共方法的雇员接口:calculatePay
,reportHours
和saveEmployee
:
class Employee {
public:
float calculatePay();
float reportHours();
void saveEmployee();
private:
float calculateRegularHours();
}
他认为这三种方法不应包含在同一类中,因为它们服务于不同的角色:首席财务官,首席运营官和首席技术官。然后,他描述了后果:如果CFO决定更改定期工作时间的计算方法,则可能会偶然发生程序员意外更改COO的计算算法的情况,因为他们依赖于相同的方法validateRegularHours。
我的问题是:遵守SRP对我们有何帮助?即使我们在两个不同的类中实现了calculatePay
和reportHours
,它们仍将依赖于相同的方法calculateRegularHours
,因此我们要么两次实现此方法(这将是代码重复),要么必须承担改变的风险会影响两个参与者的风险。
我看不到哪一点?您将如何处理这种特殊情况?
感谢您的答复!
答案 0 :(得分:0)
要么我们两次实现了此方法(这将是代码重复)
它看起来像代码重复,但不是。 calculateRegularHours
和calculatePay
使用的reportHours
的实现是相同的,这只是偶然。
由于calculatePay
和reportHours
服务于不同的参与者,因此它们将在不同的时间因不同的原因而变化。因此,这些参与者之一可能会请求其他参与者不希望的更改。因此,当涉及到此请求时,您会怎么做?我猜您会将calculateRegularHours
逻辑分为2个实现。一个用于calculatePay
,另一个用于reportHours
。但是也有可能您忘记了它,并且会在与您要进行的更改无关的地方破坏系统。这会使系统变得脆弱。
罗伯特·C·马丁(Robert C. Martin)在this video中进行了解释(39:26-43:00)。
我认为违反SRP的一个更好的例子是将为UI提供服务的方法放在业务对象中,甚至将SQL放在视图中。
无论您做什么,都应该进行测试,因为这些测试可以表明您在其他完整区域破坏了系统。如果发生这种情况,您应该重新考虑设计并记住SRP。