【问题标题】:Do "return success" methods violate the single responsibility principle?“返回成功”的方法是否违反单一责任原则?
【发布时间】:2014-04-06 21:34:00
【问题描述】:
public class FooList {
    public boolean add(Foo item) {
        int index = indexOf(item.getKey());
        if (index == -1) {
            list.add(item);
        }
        return index == -1;
    }
}

由于这增加了一个项目并且返回一个成功值,是否违反了单一职责原则?如果有,有关系吗?

另一种方法是抛出异常:

public class FooList {
    public boolean add(Foo item) throws FooAlreadyExistsException {
        int index = indexOf(item.getKey());
        if (index == -1) {
            list.add(item);
        } else {
            throw new FooAlreadyExistsException();
        }
    }
}

但这是否也违反了单一职责原则?该方法似乎有两个任务:如果该项目不存在,则添加它;否则,抛出异常。


额外问题:可以返回 null 的方法是否违反了单一职责原则?这是一个例子:

public class FooList {
    public Foo getFoo(String key) {
        int index = indexOf(key);
        return (index == -1) ? null : list.get(index);
    }
}

是返回 Foo 还是 null,取决于具体情况,“做两件事”?

【问题讨论】:

    标签: oop single-responsibility-principle


    【解决方案1】:

    这个怎么样:

    public class MyVector{
        private int[] data;
        private int count;
    
        public void add(int value){
            data[count]=value;
            ++count;
        }
    }
    

    add 做了两件事 - 它更新 data 并增加 count。根据单一职责规则,我应该将其拆分为两个功能:

    public void MyVector{
        private int[] data;
        private int count;
    
        public void add(int value){
            data[count]=value;
        }
        public void inc(){
            ++count;
        }
    }
    

    这 - 显然 - 打破了 OOP 的基础。我想要 datacount 一起改变 - 这就是将它们捆绑在一个班级中的全部意义!

    如果你像这样应用单一责任规则,你不会走得太远。如果每个方法只能做一件事,那么整个程序只能做一件事,而当一件事的定义就像上面例子中使用的那样,你的程序就不能做任何有趣的东西。

    问题是 - 这不是单一责任规则的运作方式:

    • 您不应努力编写无法以指定多个事物的方式定义的方法。相反,您应该编写可以有意义且充分定义的方法,以指定它们所做的唯一事情。

    • 您不应该根据实现来定义一件事 - 您应该根据承载该方法的类的抽象来定义它。

    • 这会有点争议:你应该对副作用更严格,对返回值不那么严格。原因是您的方法的用户忽略返回值比忽略副作用更容易。

    • 永远不应将异常算作“该方法正在做另一件事”。它们不是该方法作用的描述的一部分——它们是例外,只有在出现问题时才会发生。这就是例外的全部意义所在。

    现在,让我们看看你的方法。实现是三件事:检查存在,添加项目,返回成功结果。但是,如果您查看抽象,您可以将其定义为添加不存在的项目 - 这是一回事!

    是的,它也返回一些东西,但是返回值很容易被忽略,所以我不会把它算作“另一件事”。该方法的用户将使用它来添加项目,因此如果他们不需要返回值,他们可以忽略它。如果反过来,他们正在使用您的方法来检查项目是否存在,他们将无法忽略添加项目的副作用,那将是很糟糕的。很坏。但是由于“额外的东西”是返回值(或异常)而不是副作用 - 你的方法没有问题。

    最重要的设计规则是不要盲目地遵循设计规则。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多