The Dependence Inversion Principle of the seven principles of design pattern

Dependency inversion (inversion) principle

1. High level modules should not rely on low-level modules, and both should rely on their abstractions;

2. Abstraction should not depend on details, and details should depend on abstraction;

3. The core idea of the dependency inversion principle is: it should be interface oriented, not implementation oriented programming;

4. The dependency inversion principle is based on the design concept that the abstraction is relatively stable relative to the variability of details. An architecture based on abstraction is much more stable than a structure based on detail. In java, abstraction refers to interfaces or abstract classes, and details are concrete implementation classes.

5. The purpose of using interfaces or abstract classes is to formulate specifications and contracts without involving any specific operations. The task of showing details is entrusted to their implementation classes.

Implementation method of dependency inversion principle:

1. Try to provide interfaces or abstract classes for each class, or both.

2. The variable life type should be an interface or an abstract class as far as possible.

3. No class should derive from a concrete class.

4. Try to follow the principle of internal substitution when using inheritance.

There are three ways to transfer dependencies:

Interface transfer, constructor transfer and setter transfer.

Case:

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

/**
 * Mail class
 */
class Email{
    public String getInfo(){
        return "Email message: hello,world!";
    }
}

/**
 * person Ability to accept messages
 * Simple and easy to think of
 * Problem: if the obtained objects are wechat, SMS, etc., you need to add a new class, and the person class also needs to add a corresponding acceptance method.
 * Solution: introduce an abstract interface IReceiver to represent the receiver, so that the person class depends on the interface
 * Because wechat and SMS belong to the receiving scope, they implement IReceiver interface respectively, which conforms to the dependency inversion principle.
 */
class Person{
    public void receive(Email email){
        System.out.println(email.getInfo());
    }
}

Use the dependency transformation principle to improve:

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

interface IReceiver{
    public String getInfo();
}

/**
 * Mail class
 */
class Email implements IReceiver{
    public String getInfo(){
        return "Email message: hello,world!";
    }
}
class WeiXin implements IReceiver{

    @Override
    public String getInfo() {
        return "Wechat message: hello,world!";
    }
}
class Person{
    public void receive(IReceiver receiver){
        System.out.println(receiver.getInfo());
    }
}

There are three ways to transfer dependencies:

public class DependencyPass {
    public static void main(String[] args) {
        /*Mode 1*/
        ChangHong changHong = new ChangHong();
        new OpenAndClose().open(changHong);
        /*Mode II*/
        new OpenAndClose2(new ChangHong2()).open();
        /*Mode III*/
        OpenAndClose3 openAndClose3 = new OpenAndClose3();
        openAndClose3.setITV3(new ChangHong3());
        openAndClose3.open();
    }
}

/*Method 1: implement dependency through interface transfer*/
//Interface of switch
interface IOpenAndClose {
    //Abstract method, receive interface
    public void open(ITV itv);
}

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

//Implementation interface
class OpenAndClose implements IOpenAndClose {
    @Override
    public void open(ITV itv) {
        itv.play();
    }
}

//instantiation 
class ChangHong implements ITV {
    @Override
    public void play() {
        System.out.println("Changhong TV on");
    }
}

/*Method 2: transfer dependencies through construction methods*/
interface IOpenAndClose2 {
    public void open();
}

interface ITV2 {
    public void play();
}

class OpenAndClose2 implements IOpenAndClose2 {
    private ITV2 itv2;

    public OpenAndClose2(ITV2 itv2) {
        this.itv2 = itv2;
    }

    @Override
    public void open() {
        itv2.play();
    }
}
//instantiation 
class ChangHong2 implements ITV2{

    @Override
    public void play() {
        System.out.println("Changhong TV 2 on");
    }
}


/*Method 3: pass dependency through setter method*/
interface IOpenAndClose3 {
    public void open();

    public void setITV3(ITV3 itv3);
}

interface ITV3 {
    public void play();
}

class OpenAndClose3 implements IOpenAndClose3 {
    private ITV3 itv3;

    @Override
    public void open() {
        itv3.play();
    }

    @Override
    public void setITV3(ITV3 itv3) {
        this.itv3 = itv3;
    }
}
//instantiation 
class ChangHong3 implements ITV3{

    @Override
    public void play() {
        System.out.println("Changhong TV 3 on");
    }
}

 

Tags: Design Pattern

Posted by speedamp on Tue, 31 May 2022 17:54:44 +0530