理解单一责任原则

ana*_*ema 7 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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

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

Jan*_*aar 8

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

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

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

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

这个问题(见列表3-5)的解决方案是埋藏在一个抽象工厂,9地下室switch语句,绝不让任何人看到它.工厂将使用switch语句来创建雇员的衍生物,以及各种功能,诸如calculatePay,isPayday,和deliverPay的适当情况下,将通过员工接口多态调度.我对switch语句的一般规则是,如果它们只出现一次就可以被容忍,用于创建多态对象

  • [单一职责主体](https://en.wikipedia.org/wiki/Single_responsibility_principle) 应该在类的上下文中看到,而不必在方法级别上看到。这就是为什么我说如果任何计算发生变化,您将需要更新这个类。如果您将此方法移动到 Employee 的派生类,那么如果计算需要更改,则只需更改该类。 (2认同)

Dav*_*rne 6

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

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

我尝试遵循 Google对此的指导方针,并寻找这些表明您正在远离 SRP 的警告标志:

  • 总结课程所做的事情包括“和”这个词。
  • 对于新的团队成员或没有经验的开发人员来说,阅读并快速“掌握”课程将具有挑战性。
  • 类具有仅在某些方法中使用的字段。
  • 类具有仅对参数进行操作的静态方法。

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