Is Interface segregation principle only a substitue for Single responsibility principle?

后端 未结 3 439
余生分开走
余生分开走 2021-02-01 17:06

Is interface segregation principle only a substitue for single responsibility principle ?

I think that if my class fulfill SRP there is no need to extract more than one

相关标签:
3条回答
  • 2021-02-01 17:35

    No. Take the example of a class whose responsibility is persisting data on e.g. the harddrive. Splitting the class into a read- and a write part would not make practical sense. But some clients should only use the class to read data, some clients only to write data, and some to do both. Applying ISP here with three different interfaces would be a nice solution.

    0 讨论(0)
  • 2021-02-01 17:48

    No.

    A class can implement multiple interfaces but it should implement the methods only applicable to it.

    Assume that you have 10+ different capabilities like Climb, Think, Learn, Apply. Class Dog can have 2 capabilities and class Cat can have 2 capabilities and class Man can have 6 capabilities. It makes sense to implement only applicable capabilities in respective classes.

    Have a look at this code.

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

    output:

    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
    

    In above example, interface segregation recommends to define 10 capabilities in 10 interfaces in stead of declaring all of them in fat interface. But it does not mean that you need different classes to meet single responsibility criteria.

    Have a look at implementation of Dog, Cat and Man classes in same example.

    0 讨论(0)
  • 2021-02-01 17:52

    I think that if my class fulfill SRP there is no need to extract more than one interface.

    Single Responsibility Principle is that a class (or a method) shouldn't have more than one reason to change (i.e. each responsible for just one feature). To honour this, you'll find yourself creating new classes as your system develops.

    E.g. if you start with a Car class & find that you need functionality to change the gears, you'll extract this into a Gearbox class. This means that if you change the mechanism behind gear changes, the parent Car class doesn't need to change. If you add power-steering to your car, you'll again extract this into it's own class. The radio would be another class.

    This cascade of abstraction will happen throughout your Car class. As you move from the Car itself downwards, you'll find that the detail increases in each class — e.g. while the Car class may have a changeGear() method to allow the user to select a gear to engage, the Gearbox class will look after the nitty-gritty of making this happen (e.g. depress the clutch, disengage the current gear, select the new gear, etc.)

    With an OO design however, we don't want to expose the details of our Gearbox to the end user — we want them to interact with our system at a high level of abstraction, without needing to know how the internals work. We also want to ring-fence these internals, so that we can change them in the future without needing the users to refactor their code (which is why we'd flag them as private or protected).

    Because of this, we let users interact with our car only through the Car class itself. This is where the Interface Segregation Principle comes in. SRP ensures that the Car class delegates its sub-components to different classes, but all of our public methods will still be called through the Car class itself. ISP ensures that rather than lumping all these together in one interface, we instead create logical distinctions & expose multiple interfaces for related functionality.

    0 讨论(0)
提交回复
热议问题