单一责任原则是否适用于职能



根据Robert C. Martin的说法,SRP指出:

一个

改变的原因永远不应该超过一个。

但是,在他的《Clean Code, Chapter 3: Functions》一书中,他展示了以下代码块:

    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是为类定义的,但事实证明它也适用于函数。其次,这个功能为什么有不止一个理由可以改变?我只能看到它因为员工的变化而改变。

您可以将上面的方法视为属于以下类的对象:

class PaymentCalculator implements Function<Employee, Money> {
  Money apply(Employee) {
    switch (e.type) {
            case COMMISSIONED:
                return calculateCommissionedPay(e);
            case HOURLY:
                return calculateHourlyPay(e);
            case SALARIED:
                return calculateSalariedPay(e);
            default:
                throw new InvalidEmployeeType(e.type);
        }  
  }
}

然后,让我们尝试找出可能修改此类的原因:

  1. 员工类型工资的变化
  2. 计算逻辑的变化(新参数如员工职位、经验等)

至少对于这两种类型的更改,您将被迫在此方法中进行更正。值得一提的是,SRP的目标是实现低耦合和高内聚力。要理解这样做的好处,试着想象你有一个大系统,有数百个类和方法,比如:calculatePay、calculateVacation、createDepartment 等。所有这些类和方法都有这样的代码。做出改变会容易吗?

附言一旦你看到很长的if-else或案例陈述,你就可以开始考虑SRP。

最新更新