03-依赖倒置原则(DIP)
1. 背景
类A是高层代码,类A直接依赖B,如果要将类A改为还要依赖C,则必须修改类A的代码来实现。在实际场景中,类A是高层,负责业务逻辑,类B和类C是低层模块,负责基本的原子操作,假如修改A,会给程序带来不必要的风险。
2. 定义
高层模块不直接依赖低层模块,二者都应该依赖其抽象(抽象类或接口),抽象不应该依赖细节,细节应该依赖抽象。
3. 解决方案
类A修改为依赖接口I,而类B和类C各自实现接口I,类A通过接口I间接的同类B和类C发生联系,这样就大大降低了类的A的修改几率。
4. 依赖倒置原则的核心
面向接口编程。
5. 依赖倒置原则基于一个事实
相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建起来的架构比以细节为基础搭建起来的架构要稳定的多。在.Net中,抽象指的是接口或者抽象类,细节就是具体的实现类,使用接口或者抽象类的目的是制定好规范和契约,而不去涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成。
6. 从框架搭建的角度来体会依赖倒置原则的好处
三层:数据库访问层、业务逻辑层、UI调用层。
1. 数据库访问层中有一个 MySqlHelp类,提供链接MySQL数据增删改查的方法。
2. 业务逻辑层有一个登录业务 CheckLogin(MySqlHelp mysql,string userName,string pwd)。
3. UI调用层要调用CheckLogin方法,这时候实例化一个MySqlHelp对象,传到CheckLogin方法中即可。
有一个天,要求支持oracle数据,所以 数据库访问层中增加了一个oracleHelper类,UI调用层按照常规实例化了一个oracleHelper对象,传到CheckLogin方法中,发现我的天!!!!CheckLogin竟然不支持oracleHelper对象,同时发现类似的 所有业务层的方法都不支持oracleHelper类,这个时候悲剧就发生了,如果全部改业务层的方法,基本上完蛋。
所以解决方案:依赖倒置原则,即面向接口编程。
1. 数据库访问层声明一个接口IHelper,里面有增删改查方法,MySqlHelp和oracleHelper都实现IHelper接口
2. 业务逻辑层有一个登录业务改为依赖接口IHelper, CheckLogin(IHelper iHelper,string userName,string pwd)
3. UI调用层要调用CheckLogin方法,想连哪个数据,就实例化哪个 eg IHelper iHelper=new MySqlHelp(); 或者 IHelper iHelper=new oracleHelper()
然后调用CheckLogin即可
这种解决方案还有一个好处:先把接口约束定义出来了,写MySqlHelp和oracleHelper的人和 业务逻辑层的人可以同时开发了,不必等数据库访问层写完后,再写业务逻辑了。
7. 以日常生活为线索的案例
一个母亲给儿子讲书上的故事,所以有一个mother类,一个book类。
public class mother
{
public void readStorey(book bk)
{
Console.WriteLine("妈妈开始讲故事");
Console.WriteLine(bk.GetContents());
} }
public class book
{
public string GetContents()
{
return "我是书上的故事";
}
}
public static void show()
{
//下面以一个更贴切的例子说明一下这个问题
//一位母亲给儿子讲书上的故事,有一个mother类 ,一个book类
mother mt = new mother();
book bk = new book();
mt.readStorey(bk); }

突然有一天,儿子要求妈妈给他将报纸上的故事,我的天,妈妈竟然不会讲。
解决方案:mother类中readStorey类不在直接依赖book类,而是依赖book和newpaper类共同实现的接口类。
public interface IGetContents
{
string GetContents();
}
public class NewBook:IGetContents
{
public string GetContents()
{
return "我是书上的内容";
}
}
public class NewsPaper:IGetContents
{
public string GetContents()
{
return "我是报纸上的内容";
}
}
public class mother
{
public void readStorey2(IGetContents bk)
{
Console.WriteLine("妈妈升级了,会依赖倒置原则了,开始讲故事");
Console.WriteLine(bk.GetContents());
}
}
public static void show()
{
//有一天,儿子要求妈妈给他讲报纸上的故事
//有一个NewsPaper类,发现妈妈竟然不会讲报纸上的故事
//所以下面重构一下代码: 新的NewBook类,NewsPaper,新的讲故事的方法readStorey2,新的接口IGetContents
IGetContents ig1 = new NewBook();
IGetContents ig2 = new NewsPaper();
mt.readStorey2(ig1);
mt.readStorey2(ig2); }

8. 个人感悟
低层模块尽量都要有抽象类或接口,或者两者都有。
变量的声明类型尽量是抽象类或接口。
使用继承时遵循里氏替换原则。
03-依赖倒置原则(DIP)的更多相关文章
- C#软件设计——小话设计模式原则之:依赖倒置原则DIP
前言:很久之前就想动笔总结下关于软件设计的一些原则,或者说是设计模式的一些原则,奈何被各种bootstrap组件所吸引,一直抽不开身.群里面有朋友问博主是否改行做前端了,呵呵,其实博主是想做“全战”, ...
- 7.12 其他面向对象设计原则3: 依赖倒置原则DIP
其他面向对象设计原则3: 依赖倒置原则DIP The Dependency Inversion Principle7.1 依赖倒置原则DIP The Dependency Inversion Pr ...
- 依赖倒置原则DIP&控制反转IOC&依赖注入DI
依赖倒置原则DIP是软件设计里一个重要的设计思想,它规定上层不依赖下层而是共同依赖抽象接口,通常可以是上层提供接口,然后下层实现接口,上下层之间通过接口完全透明交互.这样的好处,上层不会因依赖的下层修 ...
- 对依赖倒置原则(DIP)及Ioc、DI、Ioc容器的一些理解
1.概述 所谓依赖倒置原则(Dependence Inversion Principle)就是要依赖于抽象,不要依赖于具体.简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模 ...
- 对依赖倒置原则(DIP)及Ioc、DI、Ioc容器的一些理解(转)
所谓依赖倒置原则(Dependence Inversion Principle)就是要依赖于抽象,不要依赖于具体.简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合 ...
- 依赖倒置原则(DIP)
什么是依赖倒置呢?简单地讲就是将依赖关系倒置为依赖接口,具体概念如下: 1.上层模块不应该依赖于下层模块,它们共同依赖于一个抽象(父类不能依赖子类,它们都要依赖于抽象类) 2.抽象不能依赖于具体,具体 ...
- 设计模式学习--面向对象的5条设计原则之依赖倒置原则--DIP
一.DIP简介(DIP--Dependency Inversion Principle): 1.高层模块不应该依赖于低层模块,二者都应该依赖于抽象.2.抽象不应该依赖于细节,细节应该依赖于抽象. ...
- 深入理解JavaScript系列(22):S.O.L.I.D五大原则之依赖倒置原则DIP
前言 本章我们要讲解的是S.O.L.I.D五大原则JavaScript语言实现的第5篇,依赖倒置原则LSP(The Dependency Inversion Principle ). 英文原文:htt ...
- IOS设计模式的六大设计原则之依赖倒置原则(DIP,Dependence Inversion Principle)
定义 高层模块不应该依赖于低层模块,二者都应该依赖于抽象:抽象不应该依赖细节:细节应该依赖抽象. 定义解读 依赖倒置原则在程序编码中经常运用,其核心思想就是面向接口编程,高层模块不应该依赖低层模块(原 ...
- 依赖倒置原则DIP(面向接口编程—OOD)
含义: 1.高层模块不应该依赖底层模块,两者都应该依赖其抽象. 2.抽象不应该依赖细节. 3.细节应该依赖抽象. 底层模块:不可分割的原子逻辑. 高层模块: 原子逻辑的再组装. 抽象:接口或者抽象类, ...
随机推荐
- Chrome 启动参数列表
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --type=gpu-process --channel ...
- 兼容IE-FireFox-Chrome的背景音乐播放
以music目录下的kn.mp3文件为例: <bgsound src="music/kn.mp3" loop="-1"/> <audio sr ...
- JDK8字符串拼接的正确姿势
1. 对列表中的元素进行拼接 以前,对一个列表中的字符串进行拼接时,常见的代码如示例1所示: 代码示例1 List<String> ids = ImmutableList.of(" ...
- fatal error: matio.h: No such file or directory
http://blog.csdn.net/zziahgf/article/details/72900948 $ sudo apt-get install libmatio-dev 或源码安装: # 下 ...
- 我的Linux系统九阴真经
在今天,互联网的迅猛发展,科技技术也日新月异,各种编程技术也如雨后春笋一样,冒出尖来了.各种创业公司也百花齐放百家争鸣,特别是针对服务行业,新型互联网服务行业,共享经济等概念的公司,越来越多.有一些公 ...
- GitHub && GitLab
1.github介绍 Git作为一个开源的分布式版本控制系统,已经被越来越多的人使用,随之需要的就是需要有个专门的地方存储.管理通过Git上传的项目,这就是gitHub gitHub是一个面向开源及私 ...
- BZOJ1222[HNOI2001]产品加工——DP
题目描述 某加工厂有A.B两台机器,来加工的产品可以由其中任何一台机器完成,或者两台机器共同完成.由于受到机器性能和产品特性的限制,不同的机器加工同一产品所需的时间会不同,若同时由两台机器共同进行加工 ...
- 详解HTTP协议
一 什么是HTTP协议 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网服务器传输超文本到本地浏览器的传送协议.HTTP 是基于 TCP/ ...
- Bicriterial routing 双调路径 HYSBZ - 1375(分层最短路)
Description 来越多,因此选择最佳路径是很现实的问题.城市的道路是双向的,每条道路有固定的旅行时间以及需要支付的费用.路径由连续的道路组成.总时间是各条道路旅行时间的和,总费用是各条道路所支 ...
- LOJ #6432. 「PKUSC2018」真实排名(组合数)
题面 LOJ #6432. 「PKUSC2018」真实排名 注意排名的定义 , 分数不小于他的选手数量 !!! 题解 有点坑的细节题 ... 思路很简单 , 把每个数分两种情况讨论一下了 . 假设它为 ...