设计模式七大原则 (3)——依赖倒转原则

一、定义

  • 高层模块不应该依赖低层模块,二者都应该依赖它们的抽象
  • 抽象不应该依赖细节,细节反而需要依赖抽象
  • 依赖倒转的中心思想使是面向接口编程
  • 依赖倒转原则所基于的设计理念 : 相较于细节的多变性,抽象的东西稳定的多;以抽象为基础的架构比以细节为基础的架构要稳定的多
    • 在Java中,抽象指的是接口或抽象类,细节是具体的实现类
  • 接口/抽象类的作用是制定规范,实现类的作用是展现细节

二、应用举例

我们使用一个 Person 类接收不同类型信息的例子来说明

2.1 方式一

class Email {
    public String getMessage() {
        return "电子邮件: " + "hello";
    }
}

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

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

运行结果:
在这里插入图片描述

  • 这个方法可以解决我们的问题
  • 但是如果我们想获取其它类型的信息(例如:QQ、微信),就得新增类,还得修改 Person 类,添加新的接收方法
  • 所以,我们可以引入一个抽象的接口 IReceiver 来表示接收者,这样 Person 类就可以和 IReceive 接口产生依赖,而 Email、WeiXin 等各自实现接口 IReceiver 就可以了,这样我们就符合依赖倒转原则了

2.2 方式二

// 接口IReceiveer表示接收者
interface IReceiver {
    String getMessage();
}

class Email implements IReceiver {
    public String getMessage() {
        return "电子邮件: " + "hello";
    }
}

class WeiXin implements IReceiver {
    public String getMessage() {
        return "微信: " + "hi";
    }
}

// 这里对接口进行依赖
class Person {
    public void receive(IReceiver receiver) {
        System.out.println(receiver.getMessage());
    }
}

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

运行结果:
在这里插入图片描述

  • 通过添加一个接口 IReceiver ,再让所有类型的信息实现这个接口,我们的信息类型就可以不断地横向拓展了
  • 同时,我们地客户端也不需要进行修改

三、依赖关系传递的三种方式

依赖关系的传递有三种方式,分别是接口传递、构造方法传递和 setter 方法传递

3.1 方式一:接口传递

请见上面 应用举例中的方式二

3.2 方式二:构造方法传递

interface IReceiver {
    String getMessage();
}

class Email implements IReceiver {
    public String getMessage() {
        return "电子邮件: " + "hello";
    }
}

class WeiXin implements IReceiver {
    public String getMessage() {
        return "微信: " + "hi";
    }
}

class Person {
    private IReceiver receiver;

    public Person(IReceiver receiver) {
        this.receiver = receiver;
    }

    public void receive() {
        System.out.println(this.receiver.getMessage());
    }
}

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

3.3 方法三:setter方法传递

interface IReceiver {
    String getMessage();
}

class Email implements IReceiver {
    public String getMessage() {
        return "电子邮件: " + "hello";
    }
}

class WeiXin implements IReceiver {
    public String getMessage() {
        return "微信: " + "hi";
    }
}

class Person {
    private IReceiver receiver;

    public void setReceiver(IReceiver receiver) {
        this.receiver = receiver;
    }

    public void receive() {
        System.out.println(this.receiver.getMessage());
    }
}

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

四、注意事项和细节

  • 低层模块尽量都要有抽象类或接口,或者两者都有
  • 变量的声明类型尽量是抽象类或接口
  • 继承时遵循里氏替换原则
  • 依赖倒转的核心就是面向接口编程

参考信息

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值