面向对象的六大设计原则(三):依赖倒置原则
2015-12-23 12:43
435 查看
三、依赖倒置原则:Dependence Inversion Principle(DIP)
定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。什么意思呢?高层模块就是调用端,底层模块就是具体的操作类。抽象是指抽象类或者接口,两者都不能直接被实例化;而细节就是具体的实现类,可以直接被实例化,也就是可以直接new出来的对象。依赖倒置原则的和核心思想就是面向接口或者说面向抽象编程。下面我们来看一个具体的例子。
这里我们做了一个简单的视频播放软件,播放一段MP4的视频。
运行结果 :
一段时间过后,来了一段AVI格式的视频,这个时候我们的视频播放器就没有办法了,于是我们必须修改代码,修改代码如下
废了九牛二虎之力,修改了所有Java类,终于AVI格式的视频也能播放了。好了,以后每当新加一种视频格式,我们就要不断的修改VideoPlayer。这显然不是我们所希望的。出现这个问题的原因就是VideoPlayer和Video高度耦合,我们必须降低他们直接的耦合。这里我们引入一个IVideo的接口
VideoPlayer和Video不再依赖于细节,而依赖于IVideo接口,这就符合我们上面所说的依赖倒置原则。修改之后的代码如下
通过这样修改之后,以后你无论新添多少中视频格式,VideoPlayer都无需修改一行代码。在实际开发中也是,一旦我们的播放器开发完成,如果反复对其进行修改的话,产生的风险是非常大,极易出现问题。这里ViderPlayer是调用端,也就是依赖倒置中的高层模块,与之相应的Video就是底层模块。这就是高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。总之一句话依赖倒置的核心思想:面向接口编程!理解了面向接口编程也就理解了依赖倒置原则!
定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。什么意思呢?高层模块就是调用端,底层模块就是具体的操作类。抽象是指抽象类或者接口,两者都不能直接被实例化;而细节就是具体的实现类,可以直接被实例化,也就是可以直接new出来的对象。依赖倒置原则的和核心思想就是面向接口或者说面向抽象编程。下面我们来看一个具体的例子。
class Video { public void run() { System.out.println("正常播放MP4视频"); } } class VideoPlayer { public void play(Video video) { video.run(); } } public class VideoTest { public static void main(String[] args) { VideoPlayer player = new VideoPlayer(); Video video = new Video(); player.play(video); } }
这里我们做了一个简单的视频播放软件,播放一段MP4的视频。
运行结果 :
<pre name="code" class="java">正常播放MP4视频
一段时间过后,来了一段AVI格式的视频,这个时候我们的视频播放器就没有办法了,于是我们必须修改代码,修改代码如下
class VideoMP4 { public void run() { System.out.println("正常播放MP4视频"); } } class VideoAVI { public void run() { System.out.println("正常播放AVI视频"); } } class VideoPlayer { public void play(VideoMP4 video) { video.run(); } public void play(VideoAVI video) { video.run(); } } public class VideoTest { public static void main(String[] args) { VideoPlayer player = new VideoPlayer(); VideoAVI video = new VideoAVI(); player.play(video); } }
废了九牛二虎之力,修改了所有Java类,终于AVI格式的视频也能播放了。好了,以后每当新加一种视频格式,我们就要不断的修改VideoPlayer。这显然不是我们所希望的。出现这个问题的原因就是VideoPlayer和Video高度耦合,我们必须降低他们直接的耦合。这里我们引入一个IVideo的接口
public interface IVideo{ public void run(); }
VideoPlayer和Video不再依赖于细节,而依赖于IVideo接口,这就符合我们上面所说的依赖倒置原则。修改之后的代码如下
class VideoMP4 implements IVideo{ public void run() { System.out.println("正常播放MP4视频"); } } class VideoAVI implements IVideo{ public void run() { System.out.println("正常播放AVI视频"); } } class VideoWMV implements IVideo{ public void run(){ System.out.prinitl("正常播放WMV视频"); } } class VideoPlayer { public void play(IVideo video) { video.run(); } } public class VideoTest { public static void main(String[] args) { VideoPlayer player = new VideoPlayer(); IVideo video = new VideoAVI(); player.play(video); } }
通过这样修改之后,以后你无论新添多少中视频格式,VideoPlayer都无需修改一行代码。在实际开发中也是,一旦我们的播放器开发完成,如果反复对其进行修改的话,产生的风险是非常大,极易出现问题。这里ViderPlayer是调用端,也就是依赖倒置中的高层模块,与之相应的Video就是底层模块。这就是高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。总之一句话依赖倒置的核心思想:面向接口编程!理解了面向接口编程也就理解了依赖倒置原则!
相关文章推荐
- Mysql,Oracle,Java数据类型对应
- C#的注释方法与数据类型
- Content-Based Information Retrieval 基于内容的信息检索
- 拷贝构造函数什么时候调用?
- C语言学习笔记--------伊能C语言学习笔记----使用指针来解决函数的副本机制
- 【转载】愚者与智者的48个差距
- poj 2395 Out of Hay(最小生成树)
- linux内核中的GPIO系统之(2):pin control subsystem
- 你为什么要努力?(很深刻)
- ARM LINUX 扩展串口
- 创业板VOL-MY 10点研究
- CBIR: Indexing and Retrieval--基于内容的图像检索:索引和检索
- C语言学习笔记----伊能C语言学习笔记-----函数的副本机制
- bzoj3110: [Zjoi2013]K大数查询 【cdq分治&树套树】
- 软件工程学习总结
- Sales Engineer
- Android 基于MVC的MVVM模式开发
- Android 基于MVC的MVVM模式开发
- 回归测试的精确化
- poj 3422 Kaka's Matrix Travels 费用流