单一职责原则适用于函数吗?

7
根据 Robert C. Martin 的说法,SRP 规定如下:

一个类的变化原因不应该超过一个。

然而,在他的书《Clean Code》第三章“函数”中,他展示了以下代码块:
    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是为类定义的,但事实证明它也适用于函数。其次,这个函数有何种“不止一个原因需要改变”的情况?我只能看到它因为Employee的改变而改变。

如果您开始在国外雇用员工,现在需要以不同的货币计算,那该怎么办呢?;) - Nir Alfasi
1个回答

2
您可以将上述方法视为属于以下类的对象:
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等)的大型系统,而所有这些类和方法都像这样编写代码。那么要进行更改是否容易呢?

P.S. 一旦您看到长长的if-else或case语句,就可以开始思考SRP。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接