其他分享
首页 > 其他分享> > 四 设计模式七大原则之依赖倒置原则

四 设计模式七大原则之依赖倒置原则

作者:互联网

1 基本介绍

依赖倒置原则是指 :

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

2 应用案例

package com.andy.principle.inversion;

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());
    }
}

**分析 : **
上面的例子中 Person 类中的 receive 的参数是Email,然后调用 getInfo 方法模拟通信. 我们试想一下,如果Person 想新添加 其他的通信方式,比如微信,短信等,那么就要新增类,而且Person 类 也要增加相应的接收方法.这样子很不利于维护和添加新功能.所以说上面的设计思路是不合适的.那么我们下面用依赖倒置原则对上面的例子进行改进.

3 改进

package com.andy.principle.inversion.improve;

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";
    }
}

class Person{
    public void receive(IReceiver receiver){
        System.out.println(receiver.getInfo());
    }
}

**分析 : **
上面的改进方案中,我们引用一个抽象的接口 IReceiver,表示接受者,这样Person 类与接口IReceiver 发生依赖,现在新增一种通信方式就只需要实现 IReceiver 类就可以了.这样就符合依赖倒置原则.
一般依赖倒置原则应该注意事项:

4 依赖关系传递的三种关系

依赖关系传递方式一种有三种:

4.1 接口传递

package com.andy.principle.inversion.improve;

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

//开关接口
interface IOpenAndClose{
    public void open(ITV tv);
}

interface ITV{
    public void play();
}

class ChangHong implements ITV{

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

//实现接口
class OpenAndClose implements IOpenAndClose{

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

**分析 : **
这里定义了两个接口 IOpenAndClose 和 ITV,并分别在类OpenAndClose 和类ChangHong中实现了这两个接口.看 IOpenAndClose 接口中的open函数,形参是ITV接口,调用是只要把实现了ITV接口的传进去就能依赖ITV接口了.这样方法有点绕,现在这个程序有点简单,看不出来这种方法的好处,但很多架构都是采用这样方法.

4.2 构造方法传递

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

interface ITV {
    public void play();//抽象方法
}

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

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

**分析 : **
像上面定义两个接口 IOpenClose 和 ITV ,而OpenAndClose 类 实现 IOpenClose ,而且OpenAndClose 类 中定义了一个 ITV属性,在OpenAndClose 类中给该属性赋值,而实现的open函数中调用ITV 的 paly方法,这也是一种方法.这也是符合依赖倒置原则的.

4.3 setter方法传递

interface IOpenAndClose{
    public void open();
    
    public void setTv(ITV tv);
}

interface ITV {
    public void play();//抽象方法
}

class OpenAndClose implements IOpenAndClose{

    private ITV tv;
    @Override
    public void open() {
        this.tv.play();
    }

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

class ChangHong implements ITV{

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

**分析 : **

setter方法传递 和 构造方法传递基本是一样的,唯一的区别在与给ITV属性的赋值一个是在构造器中,一个赋值在setter方法中.

andyonlines 发布了19 篇原创文章 · 获赞 1 · 访问量 228 私信 关注

标签:原则,tv,void,接口,class,ITV,倒置,设计模式,public
来源: https://blog.csdn.net/andyonlines/article/details/104084942