Нарушают ли методы "возврата успеха" принцип единой ответственности?

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();
        }
    }
}

Но будет ли это также нарушать принцип единоличной ответственности? Кажется, что у метода есть две задачи: если элемент не существует, добавьте его; иначе, брось исключение.


Дополнительный вопрос: не нарушают ли методы, которые могут возвращать нуль, принцип единственной ответственности? Вот пример:

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

Возвращает ли Foo или null, в зависимости от ситуации, "выполнение двух вещей"?

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;
    }
}

что, очевидно, разрушает саму основу ООП. Я хочу data а также count изменить вместе - вот в чем смысл объединять их в одном классе!

Вы не очень далеко продвинетесь, если примените правило единственной ответственности, как это. Если каждый метод может делать только одну вещь, тогда вся программа может делать только одну вещь, и когда определение одной вещи похоже на определение, использованное в приведенном выше примере, ваша программа не может сделать ничего интересного.

Дело в том, что не так работает правило единственной ответственности:

  • Вы не должны стремиться писать методы, которые не могут быть определены таким образом, который определяет более чем одну вещь. Вместо этого вы должны написать метод, который может быть осмысленно и в достаточной степени определен так, чтобы указывать только одну вещь, которую они делают.

  • Вы не должны определять одну вещь на основе реализации - вы должны определять ее на основе абстракции класса, в котором размещается метод.

  • Это будет немного спорным: Вы должны быть более строгими в отношении побочных эффектов и менее строгих в отношении возвращаемых значений. Причина заключается в том, что пользователю ваших методов легче игнорировать возвращаемые значения, чем игнорировать побочные эффекты.

  • Исключения никогда не должны учитываться как "метод делает другое". Они не являются частью описания того, что делает метод - они являются исключением из этого, что происходит только в том случае, если что-то идет не так. Вот и весь смысл исключений.

Теперь давайте посмотрим на ваш метод. Реализация состоит из трех вещей: проверка существования, добавление элемента и возврат результата успеха. Но если вы посмотрите на абстракцию, вы можете определить ее как добавление элемента, если он не существует - и это одна вещь!

Да, он также что-то возвращает, но возвращаемые значения можно легко игнорировать, поэтому я бы не посчитал это "другой вещью". Пользователи метода будут использовать его для добавления элементов, поэтому они могут игнорировать возвращаемые значения, если им это не нужно. Если бы все было наоборот, и они использовали ваш метод для проверки существования элементов, они не смогли бы игнорировать побочный эффект добавления элемента, и это было бы плохо. Очень плохой. Но поскольку "дополнительная вещь" - это возвращаемое значение (или исключение), а не побочный эффект - с вашим методом проблем нет.

Самое важное правило дизайна - не слепо следовать правилам дизайна.

Другие вопросы по тегам