高层次的模块不要依赖低层次的模块,二者都应该依赖于其抽象

抽象不应该依赖于具体,而是具体应该依赖于抽象

为了更好理解该原则,首先明确以下概念:

  • 高层次模块:也叫上层代码,一般可以认为是调用方(客户端)。以系统三层结构(表示层,业务逻辑层,数据访问层)为例子,表示层相对于业务逻辑层来说,就是高层;业务逻辑层相对于数据访问层来说就是高层;

  • 底层次模块:也叫作下层代码,一般可以认为是被调用方(提供服务的一方)。如上例子,业务逻辑层相对于表示层来说,就是底层;数据访问层相对于业务逻辑层来说,就是底层。

  • 抽象:设计原则/模式中的抽象可以理解为约束/规范,代码中表现为接口/抽象类

  • 具体:抽象的具体化,代码中表现为实现类/抽象类的派生

比如:鱼类和鸟类是具体类,动物类是抽象类;游泳类和飞行类是具体类 ,行为类是抽象类;App端签到类和PC端签到类是具体类,签到行为类是抽象类。

系统三层结构:https://blog.csdn.net/weixin_28683065/article/details/119067965

考虑以下案例:实现一个多终端(App、PC、…)签到的系统

实例1:

#include <iostream>class AppClient
{public:void signIn() {std::cout<<"App签到成功!"<<std::endl;}
};class PCClient
{public:void signIn() {std::cout<<"PC签到成功!"<<std::endl;}
};class User
{public:void signInApp(AppClient* client) {client->signIn();}void signInPC(PCClient* client) {client->signIn();}
};class App
{public:void appRun() {User* user = new User;user->signInApp(new AppClient);user->signInPC(new PCClient);}
};int main() {App app;app.appRun();return 1;
}

上述实例中,AppClient类、PCClient类、User类、App类都是具体类,没有抽象;按照层次划分,AppClient和PCClient类相对于User类是低层次类,User类相对于App类是低层次类。

存在的缺点为:

  • App类(高)需要调用User类(低)的方法实现不同签到,如果User类更改(增加或者删除)某些签到方法,App类中也要做响应的更改。此时App类严重依赖User类,违反了原则中的 [高层次的模块不要依赖低层次的模块]

  • 同时,本实例中App具体类依赖User具体类;User具体类依赖AppClient/PCClient具体类,没有抽象类的设计,违反了 [而是具体应该依赖于抽象]

  • User类需求变动时,比如添加了小程序签到,User类就必须变更添加小程序签到的方法。同时违反了开闭原则中的[对拓展开放,对修改关闭]原则

开闭原则见:。。。。。。。

因此对上述代码依照设计原则进行修改,将不同的具体签到方式抽象为签到接口类,让User类不再依赖具体的AppClient和PCClient类,而是依赖抽象接口类(签到接口类);同时期望User类是稳定地,不会因为签到方法的增多而改变User代码,实现高层次代码不依赖低层次代码。

示例2:

#include <iostream>//接口类
class ISign {public:virtual void signIn() = 0; //纯虚函数
};//具体依赖抽象
class AppClient : public ISign {public:virtual void signIn() override {std::cout<<"App签到成功!"<<std::endl;}
};class PCClient : public ISign  {public:virtual void signIn() override {std::cout<<"PC签到成功!"<<std::endl;}
};
//add new function
class WechatClient : public ISign  {public:virtual void signIn() override {std::cout<<"Wechat签到成功!"<<std::endl;}
};//稳定点: 高层模块不依赖低层次的模块,二者依赖抽象
//增加新的签到方法时,不影响User类
class User {public:void signIn(ISign* sign) {sign->signIn();}
};class App
{public:void appRun() {User* user = new User;ISign* signPC = new PCClient;ISign* signApp = new AppClient;//add new function ISign* signWeChat = new WechatClient;user->signIn(signApp);user->signIn(signApp);user->signIn(signPC);//add new function user->signIn(signWeChat);user->signIn(signWeChat);}
};int main() {App app;app.appRun();return 1;
}

入门设计原则C++实现五:依赖倒置原则相关推荐

  1. 面向对象思想 常说的OOP五大原则就是指1、单一职责原则; 2、开放闭合原则; 3、里氏替换原则; 4、依赖倒置原则; 5、接口隔离原则。...

    常说的OO五大原则就是指其中的 : 1.单一职责原则: 2.开放闭合原则: 3.里氏替换原则: 4.依赖倒置原则: 5.接口隔离原则. https://blog.csdn.net/Anders_Zhu ...

  2. 软件设计原则(四)依赖倒置原则 -Dependence Inversion Principle

    依赖倒转原则就是要依赖于抽象,不要依赖于实现.(Abstractions should not depend upon details. Details should depend upon abst ...

  3. 五大软件设计原则学习笔记5——依赖倒置原则

    五大软件设计原则SOLID: 单一职责原则(Single responsibility principle,SRP)开放封闭原则(Open–closed principle,OCP)Liskov 替换 ...

  4. 设计模式六大原则(3)——依赖倒置原则

    定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象:抽象不应该依赖细节:细节应该依赖抽象. 问题由来:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成.这种场景下,类A一 ...

  5. 依赖倒置原则_面向对象的设计原则你不要了解一下么?

    昨天我看了单一职责原则和开闭原则,今天我们再来看里式替换原则和依赖倒置原则,千万别小看这些设计原则,他在设计模式中会有很多体现,所以理解好设计原则之后,那么设计模式,也会让你更加的好理解一点. 前言 ...

  6. 软件设计原则之里氏替换原则、依赖倒置原则

    系列文章目录 软件设计原则之单一职责原则.开闭原则 软件设计原则之里氏替换原则.依赖倒置原则 软件设计原则之接口隔离原则.合成复用原则.迪米特原则 文章目录 系列文章目录 一.里氏替换原则 什么是里氏 ...

  7. 面向对象设计原则-03依赖倒置原则

    面向对象设计原则-03依赖倒置原则 依赖倒置原则的定义 依赖倒置原则(Dependence Inversion Principle,DIP)是 Object Mentor 公司总裁罗伯特·马丁(Rob ...

  8. 依赖倒置原则——面向对象设计原则

    前两节我们详细介绍了面向对象设计原则中的开闭原则和里氏替换原则,在本节中我们来介绍依赖倒置原则. 依赖倒置原则的定义 依赖倒置原则(Dependence Inversion Principle,DIP ...

  9. 设计原则——依赖倒置原则

    1.全称 Dependence Inversion Principle 缩写为:DIP 2.解释 高层模块不应该依赖低层模块,两者都应该依赖其抽象:抽象不应该依赖细节,细节应该依赖抽象 其核心思想是: ...

最新文章

  1. 汇总同一时间段的数据_数据集干货:一文读懂Mapsidejoin
  2. Windows程序设计“圣经”
  3. Linux服务器下的HTTP抓包分析
  4. [转]浅析Tomcat、JBOSS、WebSphere、WebLogic、Apache
  5. tcga癌症亚型获取_亚型多态性应用于元组的危险
  6. CCNP-第十一篇-BGP(三)(精髓篇)
  7. 计数排序和桶排序 java代码实现
  8. IOS UIWindow 和 UIScreen
  9. express不是内部或外部命令,也不是可运行的程序或批处理文件
  10. 【转】POP3、SMTP和IMAP之间的区别和联系
  11. 通过路由远程计算机重启,路由器怎么重启?这几种方法教你重启怎么弄!
  12. 面试常备题---插入排序
  13. Mysql之统计数据
  14. 什么是电脑pe系统?
  15. 软件测试面试题--银行面试
  16. 操作MySQL出错提示“BLOB/TEXT column used in key specification without a key length”解决办法
  17. linux startx无效_Linux使用startx不能进入图形界面解决方案
  18. 南华大学计算机学院赵畅,资源环境与安全工程2020年“砥砺六十载,逐梦新时代”元旦师生联欢会顺利举办...
  19. 大华linux密码,Linux用户和组的实战练习
  20. 微信开发者工具首次登陆提示网络连接失败

热门文章

  1. EasyRecovery免费电脑硬盘数据恢复软件使用教程
  2. 火狐浏览器弹性布局没有开启的问题
  3. centos下的vim安装
  4. 什么是switch语句?
  5. 如何在行业内苟住(老手勿喷)
  6. 最新微信记录恢复工具MMRecovery的下载与使用方法
  7. 目前国内可用的前端库及Zdir自建前端库
  8. SSM+图书馆电子文件资源管理 毕业设计-附源码091426
  9. 每天学一个 Linux 命令(89):alias/unalias
  10. 「我是为“数据”去的京东」对话京东供应链首席科学家申作军