本文引用自本人公众号文章:
嵌入式开发中的两点编程思想
c语言也很讲究设计模式?一文讲透
包含如下:
01)c语言和设计模式(继承、封装、多态)
02)c语言和设计模式(访问者模式)
03)c语言和设计模式(状态模式)
04)c语言和设计模式(命令模式)
05)c语言和设计模式(解释器模式)
06)c语言和设计模式(备忘录模式)
07)c语言和设计模式(观察者模式)
08)c语言和设计模式(桥接模式)
09)c语言和设计模式(建造者模式)
10)c语言和设计模式(中介者模式)
11)c语言和设计模式(策略模式)
12)c语言和设计模式(适配器模式)
13)c语言和设计模式(装饰模式)
14)c语言和设计模式(享元模式)
15)c语言和设计模式(代理模式)
16)c语言和设计模式(外观模式)
17)c语言和设计模式(迭代器模式)
18)c语言和设计模式(抽象工厂模式)
19)c语言和设计模式(责任链模式)
20)c语言和设计模式(工厂模式)
21)c语言和设计模式(模板模式)
22)c语言和设计模式(组合模式)
23)c语言和设计模式(原型模式)
24)c语言和设计模式(单件模式)
25)c语言和设计模式(开篇)
-----------------------
01)c语言和设计模式(继承、封装、多态)
记得还在我们大学c++第一门课的时候,老师就告诉我们说,c++是一门面向对象的语言。c++有三个最重要的特点,即继承、封装、多态。等到后来随着编码的增多和工作经验的积累,我也慢慢明白了面向对象的含义。可是,等我工作以后,使用的编程语言更多的是c语言,这时候我又想能不能把c语言变成面向对象的语言呢?等到后来通过思考和实践,我发现其实c语言也是可以面向对象的,也是可以应用设计模式的,关键就在于如何实现面向对象语言的三个重要属性。
(1)继承性
typedef struct _parent
{
int data_parent;
}parent;
typedef struct _child
{
struct _parent parent;
int data_child;
}child;
在设计c语言继承性的时候,我们需要做的就是把基础数据放在继承的结构的首位置即可。这样,不管是数据的访问、数据的强转、数据的访问都不会有什么问题。
(2)封装性
struct _data;
typedef void (*process)(struct _data* pdata);
typedef struct _data
{
int value;
process pprocess;
}data;
封装性的意义在于,函数和数据是绑在一起的,数据和数据是绑在一起的。这样,我们就可以通过简单的一个结构指针访问到所有的数据,遍历所有的函数。封装性,这是类拥有的属性,当然也是数据结构体拥有的属性。
(3)多态
typedef struct _play
{
void* pdata;
void (*start_play)(struct _play* pplay);
}play;
多态,就是说用同一的接口代码处理不同的数据。比如说,这里的play结构就是一个通用的数据结构,我们也不清楚pdata是什么数据,start_play是什么处理函数?但是,我们处理的时候只要调用pplay->start_play(pplay)就可以了。剩下来的事情我们不需要管,因为不同的接口会有不同的函数去处理,我们只要学会调用就可以了。
-----------------------
02)c语言和设计模式(访问者模式)
不知不觉当中,我们就到了最后一种设计模式,即访问者模式。访问者模式,听上去复杂一些。但是,这种模式用简单的一句话说,就是不同的人对不同的事物有不同的感觉。比如说吧,豆腐可以做成麻辣豆腐,也可以做成臭豆腐。可是,不同的地方的人未必都喜欢这两种豆腐。四川的朋友可能更喜欢辣豆腐,江浙的人就可能对臭豆腐更喜欢一些。那么,这种情况应该怎么用设计模式表达呢?
typedef struct _tofu
{
int type;
void (*eat) (struct _visitor* pvisitor, struct _tofu* ptofu);
}tofu;
typedef struct _visitor
{
int region;
void (*process)(struct _tofu* ptofu, struct _visitor* pvisitor);
}visitor;
就是这样一个豆腐,eat的时候就要做不同的判断了。
void eat(struct _visitor* pvisitor, struct _tofu* ptofu)
{
assert(null != pvisitor && null != ptofu);
pvisitor->process(ptofu, pvisitor);
}
既然eat的操作最后还是靠不同的visitor来处理了,那么下面就该定义process函数了。
void process(struct _tofu* ptofu, struct _visitor* pvisitor)
{
assert(null != ptofu && null != pvisitor);
if(ptofu->type == spicy_food && pvisitor->region == west ||
ptofu->type == strong_smell_food && pvisitor->region == east)
{
printf(i like this food!\n);
return;
}
printf(i hate this food!\n);
}
-----------------------------------------------------
03)c语言和设计模式(状态模式)
状态模式是协议交互中使用得比较多的模式。比如说,在不同的协议中,都会存在启动、保持、中止等基本状态。那么怎么灵活地转变这些状态就是我们需要考虑的事情。假设现在有一个state,
typedef struct _state
{
void (*process)();
struct _state* (*change_state)();
}state;
说明一下,这里定义了两个变量,分别process函数和change_state函数。其中proces函数就是普通的数据操作,
void normal_process()
{
printf(normal process!\n);
}
change_state函数本质上就是确定下一个状态是什么。
struct _state* change_state()
{
state* pnextstate = null;
pnextstate = (struct _state*)malloc(sizeof(struct _state));
assert(null != pnextstate);
pnextstate ->process = next_process;
pnextstate ->change_state = next_change_state;
return pnextstate;
}
所以,在context中,应该有一个state变量,还应该有一个state变换函数。
typedef struct _context
{
state* pstate;
void (*change)(struct _context* pcontext);
}context;
void context_change(struct _context* pcontext)
{
state* ppre;
assert(null != pcontext);
ppre = pcontext->pstate;
pcontext->pstate = ppre->changestate();
free(ppre);
return;
}
东芝芯片被收购最新消息,180亿美元卖身贝恩资本苹果是最大赢家
简单的将Vsupply 与负载接通的开关控制电路
物联网与视频媒介相关的应用有哪些
三星note7爆炸原因真相大白信任危机就过去了吗?
有源滤波器APF和静止无功发生器SVG在石油行业中的应用
嵌入式软件设计模式 好文值得收藏
GetError与GetErrorID指令的使用
大数据时代需要智能云存储 边缘智能存储是新的风口?
STM32时钟与GPIO分析 基于STM32的LED灯开发
蓝牙5与WiFi有什么优势 蓝牙5与WiFi如何选择
国产射频前端芯片未来可期
关于UR4205C的日光灯方案设计分析
再不革命,魅族将成为下一个乐视?Pro7还能背水一战吗?
亲子家庭重要成员——佳能LEGRIA HF R86
华为推送鸿蒙2.0系统开发者测试版,拥有功能独特设计
小米MIX和华为荣耀magic:最强国产旗舰互怼,孰强孰弱
魏德米勒工业分析:兼备数据科学研究与专业技能
土壤温湿度传感器教你科学种茶,从此种茶不再难
丹麦miniBOOSTER增压器HC3-4.0-B-1
爱普生QMEMS技术是什么?