理解单一责任原则

我很困惑如何确定单个方法是否有一个责任,就像清洁代码一书中的以下代码一样

public Money calculatePay(Employee e) throws InvalidEmployeeType { switch (e.type) { case COMMISSIONED: return calculateCommissionedPay(e); case HOURLY: return calculateHourlyPay(e); case SALARIED: return calculateSalariedPay(e); default: throw new InvalidEmployeeType(e.type); } } 

正如作者在这段代码中所说:“…… 显然不止一件事。第三,它违反了单一责任原则(SRP),因为改变它的原因不止一个。 ” 乍一看我的代码我在想这个方法如何违反SRP,因为如果代码发生了变化,那么只有当有一个添加的员工类型但是我试图理解方法时才会成为switch语句我进一步想出了为什么它违反了上述原则。

我的假设是,由于方法的名称是calculatePay(Employee e) ,因此该方法的唯一责任是支付计算,因为方法的名称建议但是因为在方法内部有一个filter过滤Employee的类型这个过滤现在是一个不同的或另一个责任,因此违反了SRP。 我不知道我是否做对了。

“……显然不仅仅是一件事。第三,它违反了单一责任原则(SRP),因为改变原因不止一个。”

你的答案就在于此。 每次添加新的Employee.Type ,该方法都必须更改。 此外,每个Employee.Type的计算也可能会更改。

更好的解决方案是为Employee创建一个抽象工厂 ,并为Employee的每个衍生工具创建自己的CalculatePay实现。 这样,当计算更改或添加新的Employee.Type时,只需要更改一个类。

以下是清洁代码的另一个摘录,更详细地解释了 –

这个问题的解决方案(见清单3-5)是将switch语句埋在一个抽象工厂9的地下室,永远不会让任何人看到它。 工厂将使用switch语句创建Employee衍生产品的适当实例,并且各种函数(如calculatePay,isPayday和deliverPay)将通过Employee接口以多态方式分派。 我对switch语句的一般规则是,如果它们只出现一次,就可以被容忍,用于创建多态对象

我通常在class级应用SRP。 它可以防止类变得太大并承担太多角色。

我将“责任”视为概念性的。 因此,我认为你的方法只有一个责任:计算工资。

我尝试遵循谷歌的指导原则并寻找这些警示标志,表明你正在离开SRP:

  • 总结课程的内容包括“和”这个词。
  • 对于新的团队成员或缺乏经验的开发人员来说,阅读并快速“获得”课程将是一项挑战。
  • 类具有仅在某些方法中使用的字段。
  • Class具有仅对参数进行操作的静态方法。

然而,另一方面,您的代码包含一个switch语句,表明您可能正在远离OCP …