1. Basic introduction

  • 1) High-level modules should not depend on low-level modules; both should depend on their abstractions
  • 2) Abstraction should not depend on details, details should depend on abstractions
  • 3) The central idea of dependency inversion is interface oriented programming
  • 4) Abstract things are more stable than details. An architecture based on abstraction is much more stable than one based on detail. In Java, abstraction refers to an interface or abstract class, and details are concrete implementation classes
  • 5) The purpose of using interfaces or abstract classes is to create specifications that do not involve any concrete operations, leaving the task of presenting the details to their implementation classes

2. Application cases

  • Define a Person class to receive emails and other messages
  • The easiest way to do it
    public class DependenceInversion {
    
        public static void main(String[] args) {
            Person person =new Person();
            person.receive(newEmail()); }}class Email{
        public String getInfo(a){
            return "Here comes the E-mail message."; }}class Person{
        public void receive(Email email){ System.out.println(email.getInfo()); }}Copy the code

The above method is easy to think of at first and easy to implement, but there are problems: if the object to accept is other information (such as wechat, letter), it needs to add new classes, and Person also needs to add corresponding receiving methods

Solution: An abstract IReceiver is introduced to represent the receiver, so that the Persion class depends on the interface IReceiver. Only Email and Weixin need to implement the IReceiver interface respectively, and other objects are added to receive other objects without modifying the Person class. This is in line with the dependency inversion principle

  • The dependency inversion principle is adopted
    public class DependenceInversion {
    
        public static void main(String[] args) {
            Person person =new Person();
            person.receive(new Email());
            person.receive(newWeixin()); }}interface IReceiver{
        String getInfo(a);
    }
    
    class Email implements IReceiver{
        public String getInfo(a){
            return "Here comes the E-mail message."; }}class Weixin implements IReceiver{
        public String getInfo(a){
            return "Wechat message is coming."; }}class Person{
        public void receive(IReceiver receiver){ System.out.println(receiver.getInfo()); }}Copy the code

The dependency inversion principle is adopted, so that other receiving objects are added, only the implementation of the IReceiver interface is needed, and the Persion class does not need to modify any code

3. Notes and details

  • Dependency pass method interface pass constructor pass setter way pass
  • The underlying modules should be made up of abstract classes or interfaces, or both, for better program stability
  • Variables are declared as abstract classes or interfaces as possible, so that there is a buffer layer between variable references and actual objects, which facilitates program expansion and optimization
  • Inheritance follows the Richter substitution principle