您的位置:首页 > 运维架构 > 网站架构

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

2015-05-27 09:12 197 查看

什么是依赖倒置原则

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

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

抽象不应该依赖细节

细节应该依赖抽象

高层模块和底层模块可能好理解些,因为每一个逻辑的实现都是由原子逻辑组成的,不可分割的原子逻辑就是低层模块,原子逻辑的再组装就是高层模块。那什么是抽象,什么是细节呢?我们不妨回到 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 的抽象逻辑发生了改变。

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

每个实现类尽可能继承于抽象类或实现了某个接口,或两者兼备,否则实现类何来抽象之说?没有抽象还怎么提供通用方法呢

调用者的调用方法尽可能使用接口或抽象类

任何类最好不要由具体实现类派生

尽量不要覆写基类方法

结合里氏替换原则使用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: