码迷,mamicode.com
首页 > 其他好文 > 详细

依赖倒置原则:避免写出架构糟糕的代码

时间:2015-05-27 10:05:05      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:设计模式   代码   接口   依赖   

什么是依赖倒置原则

依赖倒置原则的原始定义为包含三个方面:

  • 高层模块不应该依赖底层模块,两者都应该依赖其抽象
  • 抽象不应该依赖细节
  • 细节应该依赖抽象

高层模块和底层模块可能好理解些,因为每一个逻辑的实现都是由原子逻辑组成的,不可分割的原子逻辑就是低层模块,原子逻辑的再组装就是高层模块。那什么是抽象,什么是细节呢?我们不妨回到 Java 语言本身去找答案吧:在 Java 中,抽象指接口或抽象类,两者均不能被实例化;细节就是实现类,实现类继承抽象类或实现接口,特点在于可被实例化,所以依赖倒置原则在 Java 中的体现为:

  • 模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖是通过接口或实现类发生的
  • 接口或抽象类不依赖于实现类
  • 实现类依赖于接口或抽象类

为什么需要依赖倒置原则

在说明之前我先举个学生打LOL的例子吧:

public class Student {
    public void playGame(LoL lol){
        System.out.println("打游戏");
    }
}
public class LoL {
    public void play() {
        System.out.println("我爱LOL");
    }
}

很普通的逻辑对吧?但大家都知道,有些学生喜欢打LOL,有些学生喜欢打DOTA啊,那怎么办?许多人第一反应就是:添加一个类呗

public class DOTA {
    public void play() {
        System.out.println("我爱DOTA");
    }
}

但添加以后问题就来了,Student 要怎么玩DOTA?我们只能乖乖地在 Student 类里添加方法,才能让 Student 玩DOTA:

public class Student {
    public void playGame(LoL lol){
        System.out.println("打游戏");
    }

    public void playGame(DOTA dota){
        System.out.println("打游戏");
    }
}

观察力敏锐的人现在可能已经察觉了,我们每一次为了实际逻辑对类进行修改时,按照这种代码架构思想来修改的话,必然会做大量的无用功,随着逻辑变得复杂,代码也将不可避免地变得越来越难读。除此以外,代码还会因逻辑的添加和修改不断地修改,那么问题来了,修改带来的 Bug 谁来处理?发生大问题的时候锅给谁?

除此以外,现在进行软件开发一般都是团队协作开发,也就是说,对某个大功能块进行开发时,会划分为多个小功能模块进行开发,如果我们按照刚刚那样进行开发,把这样的代码提供给队友用,你觉得沟通效率会高吗?

这是以上的问题,导致了依赖倒置原则的诞生,依赖倒置原则就是用来减少类间耦合,提高系统的稳定性,可维护性,代码可读性的。我们不妨看看用依赖倒置原则重构的代码的例子:

首先引入抽象类 Game:

public abstract class Game {
    public abstract void play();
}

LOL 和 DOTA 类都不改变,只是让它们继承于 Game 类:

public class LoL extends Game{
    public void play() {
        System.out.println("我爱LOL");
    }
}
public class DOTA extends Game{
    public void play() {
        System.out.println("我爱DOTA");
    }
}

修改 Student 类,让它依赖于抽象:

public class Student {
    public void playGame(Game game){
        game.play();
    }
}

经过重构之后,我们无论添加多少个游戏,都不需要修改 Student 类,除非 Game 的抽象逻辑发生了改变。

怎么避免违反依赖倒置原则

  • 每个实现类尽可能继承于抽象类或实现了某个接口,或两者兼备,否则实现类何来抽象之说?没有抽象还怎么提供通用方法呢
  • 调用者的调用方法尽可能使用接口或抽象类
  • 任何类最好不要由具体实现类派生
  • 尽量不要覆写基类方法
  • 结合里氏替换原则使用

依赖倒置原则:避免写出架构糟糕的代码

标签:设计模式   代码   接口   依赖   

原文地址:http://blog.csdn.net/u012403246/article/details/46042149

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!