依赖倒置原则:避免写出架构糟糕的代码
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 的抽象逻辑发生了改变。
怎么避免违反依赖倒置原则
每个实现类尽可能继承于抽象类或实现了某个接口,或两者兼备,否则实现类何来抽象之说?没有抽象还怎么提供通用方法呢调用者的调用方法尽可能使用接口或抽象类
任何类最好不要由具体实现类派生
尽量不要覆写基类方法
结合里氏替换原则使用
相关文章推荐
- 写出优化的ARM架构上的C代码
- 如何一步一步写出MVP架构的代码
- Asterisk 代码架构概述
- MVC架构下的导出为excel的代码
- C++和C代码互相调用是不可避免的
- 后端代码架构其一
- 代码中如何避免过多的if else
- 五种方法让你立刻写出更棒的CSS代码
- My.Ioc 代码示例——避免循环依赖
- Delphi三层网络架构代码实现
- 【开发习惯】一、Java编程写出好代码
- Jive论坛与Spring框架,经典代码和架构!
- 什么时候应该避免写代码注释?
- 代码之美 - 如何写出优雅的PHP代码
- 如何写出难以维护的代码--代码命名
- 如何写出好的代码(一)
- 大恶人吉日嘎拉之走火入魔闭门造车之.NET疯狂架构经验分享系列之(五)代码复用
- 如何写出无法维护的代码
- 如何写出优美的 C 代码
- 代码重构-Android解嵌套。避免多层回调嵌套。