"return success"方法是否违反了单一责任原则?


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 是"做两件事"吗?

这个怎么样:

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一起改变 - 这就是将它们捆绑在一个班级中的全部意义!

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

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

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

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

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

  • 例外不应计为"该方法正在做另一件事"。它们不是方法功能描述的一部分 - 它们是例外,只有在出现问题时才会发生。这就是例外的重点。

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

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

最重要的设计规则

是不要盲目遵循设计规则。

最新更新