设计模式之依赖倒转原则

基本介绍

依赖倒转原则(Dependence Inversion Principle)是指:

  1. 细节应该依赖抽象
  2. 依赖倒转(倒置)的本质是面向接口编程
  1. 依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。在Java中,抽象指的是接口或抽象类,细节就是具体的实现类
  2. 使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成
反例:
public class Sms {

    public String getMsg(){
        return "hello world";
    }
}

public class Mobile {
    public void receiveMsg(Sms sms){
        System.out.println(sms.getMsg());
    }
}

public class Main {
    public static void main(String[] args) {
        Mobile mobile = new Mobile();
        Sms sms = new Sms();
        mobile.receiveMsg(sms);

    }
}

如上Mobile类的receiveMsg方法参数是具体的对象Sms,如果以后还需要接收其他类型的数据,比如微信等,需要重新写方法,非常不利于扩展,改动大。

正例:

改成面向接口对象即可。


public interface IMsg {
    String getMsg();
}

public class Sms implements IMsg{

    public String getMsg(){
        return "hello world";
    }
}

public class WeChatMsg implements IMsg{

    @Override
    public String getMsg() {
        return "WeChat is ok";
    }
}

public class Mobile {
    public void receiveMsg(IMsg sms){
        System.out.println(sms.getMsg());
    }
}

public class Main {
    public static void main(String[] args) {
        Mobile mobile = new Mobile();
        IMsg sms = new Sms();
        mobile.receiveMsg(sms);

        IMsg weChatMsg = new WeChatMsg();
        mobile.receiveMsg(weChatMsg);
    }
}

依赖关系传递的三种方式和应用案例
  1. 接口传递
public interface Run {
    void run();
}

public interface Fly {
    void flyHigh(Run run);
}

public class QuickRun implements Run{

    @Override
    public void run() {
        System.out.println("飞奔。。。");
    }
}

public class DuckFly implements Fly{
    @Override
    public void flyHigh(Run run) {
        run.run();
        System.out.println("飞不高");
    }
}

public class Main {
    public static void main(String[] args) {
        Run quickRun = new QuickRun();
        Fly duckFly = new DuckFly();
        duckFly.flyHigh(quickRun);
    }
}

  1. 构造方法传递
public interface Run {
    void run();
}

public interface Fly {
    void flyHigh();
}

public class QuickRun implements Run {

    @Override
    public void run() {
        System.out.println("飞奔。。。");
    }
}

public class DuckFly implements Fly {

    Run run;

    public DuckFly(Run run) {
        this.run = run;
    }

    @Override
    public void flyHigh() {
        run.run();
        System.out.println("飞不高");
    }
}

public class Main {
    public static void main(String[] args) {
        Run quickRun = new QuickRun();
        Fly duckFly = new DuckFly(quickRun);
        duckFly.flyHigh();
    }
}

  1. setter 方法传递(较少使用)
public interface Run {
    void run();
}

public interface Fly {
    void flyHigh();
}

public class QuickRun implements Run {

    @Override
    public void run() {
        System.out.println("飞奔。。。");
    }
}

public class DuckFly implements Fly {

    Run run;


    @Override
    public void flyHigh() {
        run.run();
        System.out.println("飞不高");
    }

    public Run getRun() {
        return run;
    }

    public void setRun(Run run) {
        this.run = run;
    }
}

public class Main {
    public static void main(String[] args) {
        Run quickRun = new QuickRun();
        DuckFly duckFly = new DuckFly();
        duckFly.setRun(quickRun);
        duckFly.flyHigh();
    }
}
依赖倒转原则的注意事项和细节
  1. 低层模块最好有接口或者实现类,这样程序稳定性好

  2. 变量的声明尽量是抽象类或者方法,这样变量引用和实际对象间有了一个缓冲,利于程序的扩展和优化

    比如我们方法参数常用List 而不是ArrayList,这样当我们需要LinkedList的时候,方法不需要改变什么就可以直接使用了。

  3. 继承时要遵循里氏替换原则(下节内容)

解释:每一个逻辑的实现都是由原子逻辑组成的,不可分割的原子逻辑就是低层模块,原子逻辑的再组装就是高层模块

代码地址:https://github.com/GilbertXiao/JavaDesignPatterns

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值