五.抽象接口与依赖反转(C面向对象开发)
内容参考于《抽象接口技术和组件开发规范及其思想》
五.抽象接口与依赖反转
基于多态可以实现“与硬件无关”的应用程序。 在 C 编程中,多态的核心解决方法是充分利用“函数指针”,抽象接口就是只包含函数指针的类, 它们非常抽象,不包含任何具体的实现,仅定义了函数的调用规则。应用不在依赖具体的实现,根据接口去编写应用。实际上之前的综合示例最后一个示例已经完全体现。
1. 示例:
时间示例
接口与应用程序(与底层无关)
itime.h
struct tm
{int tm_sec; // 秒, 0 ~59int tm_min; // 分, 0 ~ 59int tm_hour; // 小时, 0 ~ 23int tm_mday; // 日期, 1 ~ 31int tm_mon; // 月份, 0 ~ 11int tm_year; // 年int tm_wday; // 星期int tm_yday; // 天数int tm_isdst; // 夏令时(一般不使用,值为 0 或-1)
};struct itime
{int (*pfn_time_get)(struct itime *p_this, struct tm *p_tm);int (*pfn_time_set)(struct itime *p_this, struct tm *p_tm);
};static inline int itime_time_get(struct itime *p_this, struct tm *p_tm)
{return p_this->pfn_time_get(p_this, p_tm);
}static inline int itime_time_set(struct itime *p_this, struct tm *p_tm)
{return p_this->pfn_time_set(p_this, p_tm);
}
app.c
void app_elec_watch(struct itime *p_time)
{struct tm now_tm;if (用户修改了当前时间){struct tm set_tm = ... // 用户设置的时间itim_time_set(p_time, &set_tm); // 设置时间}itime_time_get(p_watch->p_rtc, &now_tm); // 获取当前时间printf("Now time is : %04d-%02d-%02d %02d:%02d:%02d \r\n",now_tm.tm_year + 1900, now_tm.tm_mon + 1, now_tm.tm_mday,now_tm.tm_hour, now_tm.tm_min, now_tm.tm_sec);// ...其它处理, 如在 LCD 上显示时间等
}
某一型号为 PCF85063 的 RTC 芯片
底层实现
pcf85063.h
#include "itime.h"struct pcf85063
{struct itime itime;
};#endif /* __PCF85063_H */
pcf85063.c
#include "pcf85063.h"static int __pcf85063_time_get(struct itime *p_this, struct tm *p_tm)
{// 首先,从 PCF85063 中获取出年、月、日、时、分、秒等信息if (获取成功){p_tm->tm_year = // 从 PCF85063 中获取出的 年 信息p_tm->tm_mon = // 从 PCF85063 中获取出的 月 信息p_tm->tm_mday = // 从 PCF85063 中获取出的 日 信息p_tm->tm_hour = // 从 PCF85063 中获取出的 时 信息p_tm->tm_min = // 从 PCF85063 中获取出的 分 信息p_tm->tm_sec = // 从 PCF85063 中获取出的 秒 信息return 0; // 获取时间成功}return -1; // 获取时间失败
}static int __pcf85063_time_set(struct itime *p_this, struct tm *p_tm)
{// 首先,将 p_tm 中的年、月、日、时、分、秒等信息设置到 PCF85063 中if (设置成功){return 0;}return -1;
}struct itime *pcf85063_init(struct pcf85063 *p_dev);
{//... PCF85063 硬件初始化p_dev->itime.pfn_time_set = __pcf85063_time_set;p_dev->itime.pfn_time_get = __pcf85063_time_get;return &p_dev->itime;
}
main.c
#include "pcf85063.h"
static struct pcf85063 pcf85063_dev;
int main()
{struct itime *p_itime = pcf85063_init(&pcf85063_dev);app_elec_watch(p_itime); // 启动“电子表”应用程序while (1);
}
2. 分析
示例中,应用程序、 接口与实现类之间的关系
传统设计应用程序和实现的关系
在面向过程的实现中,main->app->pcf85063。如果pcf85063有变化和改动的话,将会影响到依赖他的上层。而这里,app依赖的是接口,只要接口不变,app是完全不会被底层影响到的。main提供什么给app,app就使用什么。如果有更多的底层,那么关系如下
所有具体的实现类都要基于接口类中定义的抽象方法来实现(功能、 函数原型等由抽象方法规定),因此,通常情况下,接口类会被很多具体的实现类所依赖,若修改了接口类,则改动会影响所有的实现类,影响范围很大。基于此,接口类应该是非常稳定的, 不应该轻易变化。 实际上, 这对接口类的定义提出了很高的要求, 接口类不能随便定义,应考虑到可能的变化,合理、正确的定义各个抽象方法。
这里APP不再依赖底层,高层模块不再依赖于低层模块,而是APP依赖的是上层main传入的参数。依赖关系颠倒了。这就是依赖反转。
五.抽象接口与依赖反转(C面向对象开发)相关推荐
- php接口类的使用,PHP面向对象开发之类中接口的应用(interface、implements)
php类中接口的应用关键字是interface.implements了,接口是一种成员属性全部为抽象或常量的特殊抽象类,下面我们看几个实例. 类中接口的应用 1.关键字:interface 2.关键字 ...
- 浅谈“面向接口编程” :依赖反转 IOC 与 DI (容器控制反转与依赖注入)
IOC:Inversion of Control Containers and the Dependency Injection "Water" by Andy Huan, Mal ...
- 【简译】关于依赖反转原则、控制反转和依赖注入的抽象的初学者指南
原文在此. ======================================分割线==================================== 介绍 文章以介绍依赖反转原则开始 ...
- 依赖反转原理,IoC容器和依赖注入:第1部分
目录 介绍 先决条件 依赖倒置原则(DIP) 总结 介绍 在处理WPF应用程序时,我遇到过诸如Unity容器,IoC,依赖注入之类的术语.当时,我很迷茫,想着这一切的需要.但后来,当我逐渐了解到它的好 ...
- 地表最强22个互联网定律和原则:炒作周期、依赖反转原则、Spotify模型……
▲ 点击上方"老于的笔记"关注公众号 回复1,免费获取B端运营地图 正文来了 精选了7个原则和15个定律,互联网人公认的牛出天际! 产品经理照着做策划,保证怼开发.怼测试.怼老板, ...
- 依赖反转原理,IoC容器和依赖注入:第5部分
目录 介绍 总览 依赖注册 实例注册 工厂注册 类型注册 样例应用程序 总结 介绍 这是我关于依赖反转原理和依赖注入的文章的第五部分也是最后一部分.在上一部分中,我实现了一个自定义容器,其功能非常有限 ...
- Java依赖于抽象不依赖于具体,依赖倒置原则(Dependecy-Inversion Principle)
依赖倒置原则(Dependence Inversion Principle,DIP)的原始定义: 高层模块不应该依赖底层模块,两者都应该依赖其抽象: 抽象不应该依赖细节: 细节应该依赖抽象. 抽象:即 ...
- DIP依赖反转原则——实现松耦合的设计
在<IoC控制反转设计原则--实现松耦合>我们将控制工作委派给其他类来完成,向松耦合设计又迈进了一步.但是我们类仍然依赖着具体的类,所以我们可以使用DIP(依赖反转原则)来进一步获得松耦合 ...
- 依赖反转(倒置)原则(Dependency inversion principle,DIP)
在软件设计.编码过程中有几个基本原则即SOLID原则,学习理解能够帮忙我们写出更健壮的代码.SOLID是五个基本原则的首字母.这五个原则如下: Single responsibility Open–c ...
最新文章
- 《疯狂Java讲义》10
- 用python修改文件内容修改txt内容的3种方法
- bootstrap4 左侧导航栏 优秀 大气_Axure导出html没有左侧菜单栏(导航栏)?——Mac Safari...
- 9.霍夫变换:圆——圆的算法、投票使用技巧、优点和缺点_2
- jdk和jre和jvm区别_JDK,JRE和JVM之间的区别
- NYOJ 570欧拉函数求和(欧拉函数数论入门)
- Python学习第一课-----绘制股票分时图
- 多次复制粘贴工具Paste Queue Mac
- 综述(十)北京在安全测试示范区上的政策与成果数据分析
- kali linux Live Usb Encrypted Persistence配置教程
- Java基础项目 开发团队分配管理系统
- 服务器您的网络已被劫持请立即修复,网页被劫持并跳转到发布网络的修复方法...
- WriteFile写文件乱码问题
- three.js 画一个旋转的立方体
- 程序员的核心竞争力分享
- 面试高薪程序员之高频面试题(一),集合,JVM,高并发多线程等
- 【python句柄获取】——简单明了的获取窗口句柄,并使用句柄操作获取相应内容(全网最详细)
- 5G智慧医疗十大应用场景,你知道多少?
- IE安全系列:IE的自我介绍 (I)
- 微信小程序和ssm交互
热门文章
- Subversion commit log 自動寄信通知
- R极简教程-10:R语言绘图基础
- 实现类似淘票票电影滑动选择的效果
- 螺丝钉 IT人员 感悟 -- 别让 IT成为金钱的奴隶(希望引起 大家的共鸣)
- C++:MFC+VS2019当你Dlg右键“转到”对话框,提示“未能完成操作,拒绝访问”,资源视图中.re显示“X在另一个编辑器中打开”。
- 传智播客开课的第四天
- 任正非:新荣耀要做华为最强竞争对手;小米集团王嵋因错误表达致歉并请辞;全球 5G 网络三分之一来自中国技术 | EA周报...
- 程序员:一个女生不主动联系你还有机会吗?
- pythonjam游戏_独游网 - 专注独立游戏,为独立游戏发声!
- 【解决】json字符串解析失败json.decoder.JSONDecodeError