理解单一责任原则

时间:2015-10-22 08:03:56

标签: java design-patterns single-responsibility-principle

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

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),因此该方法的唯一责任是支付计算,因为方法的名称建议但是因为在方法内部有一个开关过滤员工的类型此过滤现在是一个不同的或另一个责任,因此违反了SRP。我不知道我是否做对了。

2 个答案:

答案 0 :(得分:7)

  

" ...显然不止一件事。第三,它违反了Single   责任原则(SRP)因为有多个原因   它可以改变。"

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

更好的解决方案是为员工创建Abstract Factory,并为员工提供自己的CalculatePay实现。这样,当计算更改或添加新的Employee.Type时,只需要更改一个类。

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

  

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

答案 1 :(得分:3)

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

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

我尝试按照Google的guidelines进行操作,并查找这些警告信号,表明您正在远离SRP:

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

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