SOLID Design Principles : Liskov Substitution Principle and Dependency Inversion Principle

笑着哭i 提交于 2021-02-18 17:26:30

问题


Just a thought and a question to the Stack Overflow and Microsoft Development Community about the OO software design principles called SOLID. What is the difference between the Liskov Substitution Principle and the Dependency Inversion Principle please ? I have thought about this for a while and I'm not sure of the difference. Please could you let me know ? Any thoughts / feedback very welcome.


回答1:


Liskov's substitution Principle states the following:

A class should be directly substitutable with its base-class

What this means is that if a child class extends a parent class, it should be directly substitutable. Image viewable here

If you look take Bird for example. Not all birds fly - but some do.

Lets look at a java example:

Bird  ostrich = new Ostrich();

If I am going to treat my ostrich as a Bird (is base/parent class), and we have functionality in Bird for that ostrich to fly, even though they shouldn't!

So we can separate out the structure: Refactored hierarchy for Liskov's

Dependency Inversion is easier when thought of as a separate principle.

If we have a class call a class. It makes it very hard to change it later and it is going to need us to change source code. Again lets look at a code example.

public class App {
    public static void main(String[] args) {
        Greeting greeting = new Greeting();
        greeting.sayHello(new Friend()); 
        greeting.sayHello(new Enemy());
    }
}

public class Greeting {
    public void sayHello(Person person) {
         person.greet();
    }
}

public interface Person {
    public void greet();
}

public class Friend implements Person {
    public void greet() {
        System.out.println("Hello my friend");
    }
}

public class Enemy implements Person {
    public void greet() {
        System.out.println("Go away");
    }
}

Here we pass a parent object (Person) of both of items (Friend and Enemy). If we passed through a Friend object, we would need a separate identical method for the Enemy method. We can use the Open/Closed principle to have a single method which can call either Friend or Enemy or anything in the future which might extend Person. Dependency inversion is that rather than the sayHello() method creating a class, the Parent object is passed through. This means that which Parent object we call is dependent on App, rather than sayHello() determining which object to call.

It is better practice to use dependency inversion. The class greet() calls is not set in stone, as long as the class being passed is that which implements Person.

What this means is that instead of App being dependent on Friend. Whether Friend or Enemy gets called is dependent on App.

Passing responsibility up like this means that our code can be easily maintained and changed. Using Context and Dependency Injection, it is possible for configuration files to determine which type of object we want to use when a specified interface is referenced.




回答2:


In one sense, the LSP and the DIP are opposites.

  • The LSP governs the relationship between classes in an inheritance hierarchy
    (i.e. classes that are parent and child).
  • The DIP governs relationships among classes outside an inheritance hierarchy
    (i.e. classes that are not parent and child).

For a visual, consider six potential relationships among two parent and two child classes.

  • LSP is concerned with relationships 1 and 2.
    • 1 and 2 are OK only if Child1 and Child2 are subtypes and not just subclasses.
  • DIP is concerned with relationships 3, 4, 5, and 6.
    • 3 is OK.
    • 6 is prohibited.
    • 4 and 5 can point upwards but not down.



来源:https://stackoverflow.com/questions/58300258/solid-design-principles-liskov-substitution-principle-and-dependency-inversion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!