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

时间:2015-03-08 17:38:28

标签: design-patterns single-responsibility-principle

根据Robert C. Martin的说法,SRP表示:

  

的更改原因应该不止一个。

然而,在他的书清洁代码,第3章:功能中,他展示了以下代码块:

    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是为类定义的,但事实证明它也适用于函数。其次,这个函数有多个原因需要改变?我只能看到它因员工的变化而发生变化。

1 个答案:

答案 0 :(得分: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. 计算逻辑的变化(新参数作为员工职位,经验等)
  3. 对于至少这两种类型的更改,您将被迫在此方法中进行更正。值得一提的是,SRP的目标是实现低耦合和高内聚。要理解这个尝试的好处,想象你有一个包含数百个类和方法的大系统:calculatePay,calculateVacation,createDepartment等。所有这些类和方法都有这样的代码。是否容易做出改变?

    P.S。一旦你看到if-else或case语句很长,你就可以开始考虑SRP了。