C与设计模式

定义

  动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案 

要点 

类图

  还是网上下的

白话

  不知道小时候有没有玩过一个游戏,游戏玩法就是几个人在一些小纸条上写上各自的名字,然后再在另外的纸条上分别写上时间、地点、和谁、干什么了,最后把这些纸条混在一起,大家随便抽,最后把各自抽到的纸条组在一起,看凑在一起的是什么话,比如有 “张三10点多在屋顶上打飞机”之类的,大家就笑了。。。。

将这个游戏代入到装饰者模式中来,很显然,写在纸上的都是 “汉字”(IObject),它们要”组合”(Method)在一起,要对人物组件 “张三”(object1)、”李四”(object2)用别的字进行包装”组合”(Method)。怎么包装呢,”随机抽”(Decorator)了”组合”(Method)在一起,哪些字可以用来抽列,就是剩下的”时间”(A_Decorator),”地点”(B_Decorator),”干什么”(C_Decorator) ,这些都是可以被抽了”组合”(Method)在一起的。最后调用某个人物的”组合”(Method)方法就成了让大家发笑的一句话了。

代码实现及实例

   装饰者模式实际上是一种迭代处理方式,吐槽一下,能不用迭代,尽量不要用迭代。

  有个酒店楼层房间管理系统,由上位机和各个楼层的信息监测设备节点组成。设备节点通过网络将数据传送给上位机。需传送的数据有很多类型,而且每种类型又包含很多子类型。截取一部分来实现。

将每次需要传送的数据包统称为一个数据帧。假设有2种数据帧,大的类型分为2个,一是固定长度的帧(Fixed_Frame),二是不固定长度的帧(UnFixed_Frame);小的类型分为4个,确认帧(Confirm_Frame)、参数帧(Param_Frame)、实时数据帧(RTData_Frame)、带时标(TFlag_Frame)

各个类型的代码实现

  

extern unsigned char frame_buffer[128];#define START_BYTE 0x68//抽象组件typedef struct _iobject{struct _iobject *prev;data_len;var_data_len; (*frame_creater)(struct _iobject *obj); //接口函数}Iobject;//具体组件Iobject Fixed_Frame;//固定帧Iobject UnFixed_Frame;//可变长度帧//具体装饰者Iobject Confirm_Frame;//确认帧Iobject Param_Frame;//参数帧Iobject RTData_Frame;//实时数据帧Iobject TFlag_Frame;//带时标//抽象的装饰者 Iobject Decorator;

抽象的装饰者Decorator可以直接用下面的decorator_frame_creater函数直接代替,为了形象点, 最后还是加上了

相关函数

  

//初始化某个Iobject的变量init_iobject(Iobject *obj,int cr_data_len,int (*frame_creater)(Iobject *m_obj)){obj->cr_data_len=cr_data_len;obj->data_len=0;obj->frame_creater=frame_creater;obj->prev=0;}add_iobject(Iobject *current,Iobject *prev){prev->data_len=current->cr_data_len+current->data_len;current->prev=prev;}decorator_frame_creater(struct _iobject *obj){obj->var_data_len=0;if(obj->prev!=0)obj->var_data_len=obj->prev->frame_creater(obj->prev);return obj->var_data_len;}Fixed_frame_creater(struct _iobject *obj){obj->var_data_len=decorator_frame_creater(obj);frame_buffer[obj->data_len]=START_BYTE;return obj->cr_data_len+obj->var_data_len;}Confirm_Frame_frame_creater(struct _iobject *obj){obj->var_data_len=decorator_frame_creater(obj);frame_buffer[obj->data_len]=0x00;frame_buffer[obj->data_len+1]=0x00;return obj->cr_data_len+obj->var_data_len;}

最后是使用

int main(void){int count=0;init_iobject(&Fixed_Frame,1,Fixed_frame_creater);init_iobject(&Confirm_Frame,2,Confirm_Frame_frame_creater);init_iobject(&Decorator,0,decorator_frame_creater);while(1){//置发送帧的一些配置选项,假设需要发送一个确认的固定帧add_iobject(&Decorator,&Fixed_Frame);add_iobject(&Fixed_Frame,&Confirm_Frame);//调用decorator的接口函数count=Decorator.frame_creater(&Decorator);//网卡发送数据帧eth_send(frame_buffer,count);}}

世上没有绝望的处境,只有对处境绝望的人。

C与设计模式

相关文章:

你感兴趣的文章:

标签云: