Подтвердить что ты не робот

Является ли принцип сепарации интерфейса только заменой принципа единой ответственности?

Является ли принцип сепарации интерфейса только заменой принципа единой ответственности?

Я думаю, что если мой класс выполняет SRP, нет необходимости извлекать более одного интерфейса.

Таким образом, ISP выглядит как решение в случае, если нам по какой-то причине нужно сломать SRP.

Я прав?

4b9b3361

Ответ 1

Нет. Возьмем пример класса, ответственность которого сохраняется за данные, например. жесткий диск. Разделение класса на часть чтения и записи не имеет практического смысла. Но некоторые клиенты должны использовать только класс для чтения данных, некоторые клиенты - только для записи данных, а некоторые - для обоих. Применение ISP здесь с тремя различными интерфейсами было бы хорошим решением.

Ответ 2

Я думаю, что если мой класс выполнит SRP, нет необходимости извлекать больше чем один интерфейс.

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

например. если вы начинаете с класса Car и обнаружите, что вам нужна функциональность для переключения передач, вы извлечете его в класс Gearbox. Это означает, что если вы измените механизм переключения передач, родительский класс Car не нуждается в изменении. Если вы добавите рулевое управление с усилителем в свой автомобиль, вы снова извлечете его в свой класс. Радио будет другим классом.

Этот каскад абстракции будет происходить в вашем классе Car. Когда вы переходите от самого Car вниз, вы обнаружите, что деталь увеличивается в каждом классе - например. в то время как класс Car может иметь метод changeGear(), позволяющий пользователю выбирать механизм для включения, класс Gearbox будет следить за тем, как это происходит (например, нажмите на муфту, отключите текущую передачу, выберите новую передачу и т.д.)

Однако с дизайном OO мы не хотим раскрывать детали нашего Gearbox конечному пользователю - мы хотим, чтобы они взаимодействовали с нашей системой на высоком уровне абстракции, не зная, как внутренние элементы Работа. Мы также хотим закрепить эти внутренние элементы, чтобы мы могли изменить их в будущем, не требуя, чтобы пользователи реорганизовали свой код (поэтому мы будем отмечать их как private или protected).

Из-за этого мы позволяем пользователям взаимодействовать с нашим автомобилем только через класс Car. В этом случае используется принцип разделения сегментов. SRP гарантирует, что класс Car делегирует свои подкомпоненты различным классам, но все наши методы public будут по-прежнему вызываться через Car сам класс. ISP гарантирует, что вместо объединения всех этих компонентов в один интерфейс мы вместо этого создадим логические различия и выставим несколько интерфейсов для связанных функций.

Ответ 3

Нет.

Класс может реализовывать несколько интерфейсов, но он должен применять методы, применимые только к нему.

Предположим, что у вас есть 10 + различных возможностей, таких как Climb, Think, Learn, Apply. Класс Dog может иметь 2 возможности, а класс Cat может иметь 2 возможности, а класс Man может иметь 6 возможностей. Имеет смысл реализовать только применимые возможности в соответствующих классах.

Посмотрите на этот код.

public class ISRDemo{
    public static void main(String args[]){

        Dog dog = new Dog("Jack",16);
        System.out.println(dog);

        Learn dl = dog;
        dl.learn();
        ProtectOwner p = dog;
        p.protectOwner();

        Cat cat = new Cat("Joe",20);
        System.out.println(cat);
        Climb c = cat;
        c.climb();
        Remember r = cat;
        cat.doRemember();       

        Man man = new Man("Ravindra",40);   
        System.out.println(man);
        Think t = man;
        t.think();
        Learn l = man;
        l.learn();
        Apply a = man;
        a.apply();
        PlaySports pm = man;
        pm.playSports();
        Remember rm = man;
        rm.doRemember();

    }
}

class Dog implements Learn,ProtectOwner{
    private String name;
    private int age;
    public Dog(String name,int age){
        this.name = name;
        this.age = age;
    }

    public void learn(){
        System.out.println(this.getClass().getSimpleName()+ " can learn");
    }
    public void protectOwner(){
        System.out.println(this.getClass().getSimpleName()+ " can protect owner");
    }
    public String toString(){
        return "Dog :"+name+":Age:"+age;
    }
}
class Cat implements Climb,Remember {
    private String name;
    private int age;
    public Cat(String name,int age){
        this.name = name;
        this.age = age;
    }
    public void climb(){
        System.out.println(this.getClass().getSimpleName()+ " can climb");
    }
    public void doRemember(){
        System.out.println(this.getClass().getSimpleName()+ " can remember");
    }
    public String toString(){
        return "Cat :"+name+":Age:"+age;
    }
}
interface ProtectOwner {
    public void protectOwner();
}
interface Remember{
    public void doRemember();
}
interface Climb{
    public void climb();
}
interface Think {
    public void think();
}
interface Learn {
    public void learn();
}
interface Apply{
    public void apply();
}
interface PlaySports{
    public void playSports();
}

class Man implements Think,Learn,Apply,PlaySports,Remember{
    String name;
    int age;

    public Man(String name,int age){
        this.name = name;
        this.age = age;
    }
    public void think(){
        System.out.println(this.getClass().getSimpleName() + " can think");
    }
    public void learn(){
        System.out.println(this.getClass().getSimpleName() + " can learn");
    }
    public void apply(){
        System.out.println(this.getClass().getSimpleName() + " can apply");
    }
    public void playSports(){
        System.out.println(this.getClass().getSimpleName() + " can play sports");
    }
    public void doRemember(){
        System.out.println(this.getClass().getSimpleName() + " can remember");
    }
    public String toString(){
        return "Man :"+name+":Age:"+age;
    }
}

выход:

java ISRDemo
Dog :Jack:Age:16
Dog can learn
Dog can protect owner
Cat :Joe:Age:20
Cat can climb
Cat can remember
Man :Ravindra:Age:40
Man can think
Man can learn
Man can apply
Man can play sports
Man can remember

В приведенном выше примере сегрегация интерфейса рекомендует определить 10 возможностей в 10 интерфейсах вместо объявления всех из них в жирном интерфейсе. Но это не значит, что вам нужны разные классы, чтобы соответствовать единым критериям ответственности.

Посмотрите на реализацию классов Dog, Cat and Man в том же примере.