Dependence inversion principle (interface-oriented programming)

basic concepts:

  1. High-level modules should not rely on low-level modules, both should rely on their abstractions
  2. Abstraction should not depend on details (concrete implementation), details (concrete implementation) should depend on abstraction
  3.  The central idea of ​​dependency inversion (inversion) is interface-oriented programming
  4. The principle of relying on inversion is based on the design concept: Compared with the variability of details, abstract things are much more stable.
    An architecture based on abstraction is much more stable than an architecture based on details. In Java, abstraction refers to an interface or abstract class, and the details are the specific implementation class
  5. The purpose of using interfaces or abstract classes is to formulate specifications without involving any specific operations, and to delegate the task of showing details to their implementation classes

Things to do with dependency inversion:

  1. Low-level modules should have abstract classes or interfaces as much as possible, or both, and the program stability is better
  2. The declaration type of the variable should be an abstract class or interface as much as possible, so that there is a buffer layer between our variable reference and the actual object, which is conducive to program expansion and optimization
  3. Follow the Richteric Substitution Principle in Inheritance

Example: the Person class receives the message from Emil: "Email message: hello, world"

Way one, traditional way

public class DependecyInversion {

	public static void main(String[] args) {
		Person person = new Person();
		person.receive(new Email());
	}

}


class Email {
	public String getInfo() {
		return "电子邮件信息: hello,world";
	}
}


class Person {
	public void receive(Email email ) {
		System.out.println(email.getInfo());
	}
}

analysis

Existing defects:

     If the objects we get are WeChat, SMS, etc., we need to add new classes, and Perons also need to add corresponding receiving methods

Solutions:

      Introduce an abstract interface IReceiver, which represents the receiver, so that the Person class and the interface IReceiver are dependent (depending on the abstraction, getting rid of the Email detail class). Because Email, WeiXin, etc. belong to the scope of receiving, they can implement the IReceiver interface, so we can Comply with the principle of dependency inversion.

This principle is very common because you will find many companies adopt this kind of thinking. Such as NetEase Cloud Api, Alipay Api and other interfaces are very common

Method two, pass dependencies through interfaces

public class DependecyInversion {

	public static void main(String[] args) {
		//客户端无需改变
		Person person = new Person();
		person.receive(new Email());
		
		person.receive(new WeiXin());
	}

}

//定义接口
interface IReceiver {
	public String getInfo();
}

class Email implements IReceiver {
	public String getInfo() {
		return "电子邮件信息: hello,world";
	}
}

//增加微信
class WeiXin implements IReceiver {
	public String getInfo() {
		return "微信信息: hello,ok";
	}
}

//方式2
class Person {
	//这里我们是对接口的依赖
	public void receive(IReceiver receiver ) {
		System.out.println(receiver.getInfo());
	}
}

 

 Way three, pass the dependency through the construction method 

public class DependencyPass {

    public static void main(String[] args) {
        ChangHong changHong = new ChangHong();
//        通过构造器进行依赖传递
		OpenAndClose openAndClose = new OpenAndClose(changHong);
		openAndClose.open();
    }

}
class ChangHong implements ITV {
    public void play() {
        // TODO Auto-generated method stub
        System.out.println("长虹电视机,打开");
    }
}

interface ITV { //ITV接口
	public void play();
}

interface IOpenAndClose {
	public void open(); //抽象方法
}

// 方式3: 通过构造方法依赖传递
class OpenAndClose implements IOpenAndClose {
	public ITV tv; //成员

	public OpenAndClose(ITV tv) { //构造器
		this.tv = tv;
	}

	public void open() {
		this.tv.play();
	}
}

 

Way four, pass the dependency through the Setter method 

public class DependencyPass {

    public static void main(String[] args) {
        ChangHong changHong = new ChangHong();
        OpenAndClose openAndClose = new OpenAndClose();
        openAndClose.setTv(changHong);
        openAndClose.open();

    }

}
class ChangHong implements ITV {
    @Override
    public void play() {
        System.out.println("长虹电视机,打开");
    }

}

interface IOpenAndClose {
    public void open(); // 抽象方法

    public void setTv(ITV tv);
}

interface ITV { // ITV接口
    public void play();
}

// 方式4 , 通过setter方法传递
class OpenAndClose implements IOpenAndClose {
    private ITV tv;

    public void setTv(ITV tv) {
        this.tv = tv;
    }

    public void open() {
        this.tv.play();
    }
}

 

 

Guess you like

Origin blog.csdn.net/qq_41813208/article/details/102982605