设计模式原则之:依赖倒转原则

基本介绍:

  1. 高层模块不应该依赖与底层模块,二者都应该依赖其抽象
  2. 抽象不应该依赖细节,细节应该依赖抽象
  3. 依赖倒转(倒置)的中心思想是面向接口编程
  4. 依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础的架构要稳定的多,在Java中,抽象指的是接口或抽象类,细节就是具体的实现类
  5. 使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给它们的实现类去完成

错误的案例+分析说明

 

/**
 * @description: 依赖倒转错误案例
 * @author: abel.he
 * @date: 2023-08-02
 **/
public class DependencyInversionError {

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

}

class Email {
    public String info() {
        return "电子邮件信息:info";
    }
}

/**
 * 完成Person接受消息的功能
 * 分析:
 * 1、简单、比较容易得到
 * 2、如果增加其他方法 如微信,短信等等 则新增类,同时Person也要增加相应的接受方法
 * 3、解决思路,引入一个抽象接口IReceiver,表示接受者,这样Person类与接口IReceiver发生依赖
 *    微信,短信 等等属于接受的范围,它们各自实现IReceiver接口就ok,这样就符合依赖倒转原则
 */
class Person {
    public void receive(Email email) {
        System.out.println(email.info());
    }
}

 

引出的案例

 

/**
 * @description: 依赖倒转正确案例
 * @author: abel.he
 * @date: 2023-08-02
 **/
public class DependencyInversionCorrect {

    public static void main(String[] args) {
        Person1 person = new Person1();
        person.receive(new Email1());
        person.receive(new WeChat());
    }
}

interface IReceiver {
    String info();
}

class Email1 implements IReceiver {
    public String info() {
        return "电子邮件信息:info";
    }
}

class WeChat implements IReceiver {

    @Override
    public String info() {
        return "微信信息:info";
    }
}

class Person1 {
    public void receive(IReceiver receiver) {
        System.out.println(receiver.info());
    }
}

 依赖关系传递的三种方式和应用场景

1.接口传递

 

/**
 * @description: 依赖倒装接口传递
 * @author: abel.he
 * @date: 2023-08-02
 **/
public class DependencyPass {

    public static void main(String[] args) {
        ChangHong changHong = new ChangHong();
        OpenAndClosed openAndClosed = new OpenAndClosed();
        openAndClosed.show(changHong);
    }

}

interface ITv {
    void play();
}

class ChangHong implements ITv {

    @Override
    public void play() {
        System.out.println("长虹电视机:打开");
    }
}

interface IOpenAndClosed {
    void show(ITv tv);
}

class OpenAndClosed implements IOpenAndClosed {

    @Override
    public void show(ITv tv) {
        tv.play();
    }
}

  

 

2.构造防范传递

 

/**
 * @description: 构造器传递
 * @author: abel.he
 * @date: 2023-08-02
 **/
public class DependencyPass1 {

    public static void main(String[] args) {
        ChangHong1 hong1 = new ChangHong1();
        OpenAndClosed1 openAndClosed1 = new OpenAndClosed1(hong1);
        openAndClosed1.show();
    }
}

interface ITv1 {
    void play();
}

class ChangHong1 implements ITv1 {

    @Override
    public void play() {
        System.out.println("长虹电视:打开");
    }
}

interface IOpenAndClosed1 {
    void show();
}

class OpenAndClosed1 implements IOpenAndClosed1{

    private ITv1 tv;

    public OpenAndClosed1(ITv1 tv) {
        this.tv = tv;
    }

    @Override
    public void show() {
        tv.play();
    }
}

 

3.setter方法传递

 

/**
 * @description: 依赖倒转案例 setter传递
 * @author: abel.he
 * @date: 2023-08-02
 **/
public class DependencyPass2 {

    public static void main(String[] args) {
        ChangHong2 changHong2 = new ChangHong2();
        OpenAndClosed2 openAndClosed2 = new OpenAndClosed2();
        openAndClosed2.setTv2(changHong2);
        openAndClosed2.show();
    }

}

interface ITv2 {
    void play();
}

class ChangHong2 implements ITv2 {

    @Override
    public void play() {
        System.out.println("长虹2 打开");
    }
}

interface IOpenAndClosed2 {
    void show();
}

class OpenAndClosed2 implements IOpenAndClosed2 {

    private ITv2 tv2;

    public void setTv2(ITv2 tv2) {
        this.tv2 = tv2;
    }

    @Override
    public void show() {
        tv2.play();
    }
}

  

 

posted @ 2023-08-02 07:35  译林  阅读(9)  评论(0编辑  收藏  举报