JAVA设原则之依赖倒置原则

JAVA设原则之依赖倒置原则

本博客大部分内容来自于网络,写下来方便以后查阅


1.什么是依赖倒置原则

简单来说
A.高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。
B.抽象不应该依赖于具体实现,具体实现应该依赖于抽象。

2.为什么要遵循依赖倒置原则
  很多时候我们更改一个需求,发现更改一处地方需要更改多个文件,看见很多的报错我们自己都觉得烦,我们很清醒的意识到这是因为严重的耦合导致的,所以自然要想办法解决这个问题
  
3.依赖倒置有什么好处
  简单来说,解决耦合。一般情况下抽象的变化概率很小,让用户程序依赖于抽象,实现的细节也依赖于抽象。即使实现细节不断变动,只要抽象不变,客户程序就不需要变化。这大大降低了客户程序与实现细节的耦合度。

例子

公司是福特和本田公司的金牌合作伙伴,现要求开发一套自动驾驶系统,只要汽车上安装该系统就可以实现无人驾驶,该系统可以在福特和本田车上使用,只要这两个品牌的汽车使用该系统就能实现自动驾驶。

常规写法

既然是两种不同的汽车,那我们分别定义出来,一个Fute一个Bentian,代码如下:

//福特汽车
public class Fute {

    public void run() {
        System.out.println("福特汽车启动");

    }

    public void stop() {
        System.out.println("福特汽车停止");

    }

}
//本田汽车
public class Bentian{

    public void run() {
        System.out.println("本田汽车启动");

    }

    public void stop() {
        System.out.println("本田汽车停止");

    }

}
//我们的自动驾驶系统
public class AtuoRunSystem {


    private String mType;
    private Bentian bentian;
    private Fute fute;

    public AtuoRunSystem(String type){
        mType = type ;
        bentian = new Bentian();
        fute = new Fute();
    } 
    public void AutoRun(){
        if ("bentian".equals(mType)) {
            bentian.run();
        }else {
            fute.run();
        }
    }
    public void AutoStop(){
        if ("bentian".equals(mType)) {
            bentian.stop();
        }else {
            fute.stop();
        }
    }
}

代码很简单,相信有java基础的人一看就懂了,但是缺点也很明显,扩展性特别差,现在只有两种车,if-else语句还算简单,假设以后有100种车呢?是不是要改很多文件,写很多的if-else语句,这样岂不是把人忙死,效率很低。
那么,接下来我们开始改造。

首先观察福特和本田两个类

  完全一模一样的代码是不是,那么我们开始抽离,写个抽象类或者接口都可以,这里我们写一个接口,有人纳闷为啥不写抽象类呢?根据我的个人见解,抽象类的抽象方法可以自己实现,但是接口的方法都是由子类实现的,车的功能我们具体细节我们不知道,没必要写出它的实现,所以,我们由子类实现,代码如下

public interface Icar {
    void run();
    void stop();
}

其次来我们看定义

A.高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。
B.抽象不应该依赖于具体实现,具体实现应该依赖于抽象。

在上述代码中,我们的AutoRunSystem类严重依赖于具体的子类,比如福特,本田,依赖了低层模块,而定义里已经说明,我们应该依赖于抽象,于是我们改造AutoRunSystem代码
代码如下:

public class AtuoRunSystem {

    private Icar icar;

    public AtuoRunSystem(Icar icar){
        this.icar = icar;
    }

    public void autoRun(){
        icar.run();

    }
    public void autoStop(){
      icar.stop();
    }

}

这样我们依赖的就是它的抽象类Icar。

public class Bentian implements Icar{

    @Override
    public void run() {
        System.out.println("本田汽车启动");

    }

    @Override
    public void stop() {
        System.out.println("本田汽车停止");

    }

}
public class Fute implements Icar{

    public void run() {
        System.out.println("福特汽车启动");

    }

    public void stop() {
        System.out.println("福特汽车停止");

    }

}

这样,我们就抽出了它的共同点。正好也呼应了B点,具体应该依赖于抽象,而不是抽象依赖于具体

这样,在main函数中,我们就可以这么使用了

public class Main {

    public static void main(String[] args) {
        AtuoRunSystem system = new AtuoRunSystem(new Bentian());
        system.autoRun();
        AtuoRunSystem system2 = new AtuoRunSystem(new Fute());
        system2.autoRun();
    }
}

是不是一下子明了多了,而且无论多少量车,我们都不用特别大改,只需要改一下抽象接口,写出它的具体实现,我们其他就不用管了,是不是很棒。
看懂这个,我们以后就可以看MVP模式了~~

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1) 优秀的程序应该是这样的:阅读时,感觉很优雅;新增功能时,感觉很轻松;运行时,感觉很快速,这就需要计模式支撑。2) 计模式包含了大量的编程思想,讲授和真正掌握并不容易,网上的计模式课程不少,大多讲解的比较晦涩,没有真实的应用场景和框架源码支撑,学习后,只知其形,不知其神。就会造成这样结果: 知道各种计模式,但是不知道怎么使用到真实项目。本课程针对上述问题,有针对性的进行了升级 (1) 授课方式采用 图解+框架源码分析的方式,让课程生动有趣好理解 (2) 系统全面的讲解了计模式,包括 计模式七大原则、UML类图-类的六大关系、23种计模式及其分类,比如 单例模式的8种实现方式、工厂模式的3种实现方式、适配器模式的3种实现、代理模式的3种方式、深拷贝等3) 如果你想写出规范、漂亮的程序,就花时间来学习下计模式吧课程内容和目标本课程是使用Java来讲解计模式,考虑到计模式比较抽象,授课采用 图解+框架源码分析的方式1) 内容包括: 计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML类图(类的依赖、泛化和实现、类的关联、聚合和组合) 23种计模式包括:创建型模式:单例模式(8种实现)、抽象工厂模式、原型模式、建造者模式、工厂模式。结构型模式:适配器模式(3种实现)、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式(3种实现)。行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)2) 学习目标:通过学习,学员能掌握主流计模式,规范编程风格,提高优化程序结构和效率的能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值