1、C语言设计模式一 、C语言和设计模式(继承、封装、多态)C+有三个最重要的特点,即继承、封装、多态。我发现其实C语言也是可以面向对象的,也是可以应用设计模式的,关键就在于如何实现面向对象语言的三个重要属性。(1)继承性cppview plaincopy1.typedefstruct_parent2.3.intdata_parent;4.5.Parent;6.7.typedefstruct_Child8.9.struct_parentparent;10.intdata_child;11.12.Child; 在设计C语言继承性的时候,我们需要做的就是把基础数据放在继承的结构的首位置即可。这样,不管
2、是数据的访问、数据的强转、数据的访问都不会有什么问题。(2)封装性cppview plaincopy1.struct_Data;2.3.typedefvoid(*process)(struct_Data*pData);4.5.typedefstruct_Data6.7.intvalue;8.processpProcess;9.10.Data; 封装性的意义在于,函数和数据是绑在一起的,数据和数据是绑在一起的。这样,我们就可以通过简单的一个结构指针访问到所有的数据,遍历所有的函数。封装性,这是类拥有的属性,当然也是数据结构体拥有的属性。(3)多态cppview plaincopy1.typede
3、fstruct_Play2.3.void*pData;4.void(*start_play)(struct_Play*pPlay);5.Play; 多态,就是说用同一的接口代码处理不同的数据。比如说,这里的Play结构就是一个通用的数据结构,我们也不清楚pData是什么数据,start_play是什么处理函数?但是,我们处理的时候只要调用pPlay-start_play(pPlay)就可以了。剩下来的事情我们不需要管,因为不同的接口会有不同的函数去处理,我们只要学会调用就可以了。二、C语言和设计模式(访问者模式)不知不觉当中,我们就到了最后一种设计模式,即访问者模式。访问者模式,听上去复杂一些
4、。但是,这种模式用简单的一句话说,就是不同的人对不同的事物有不同的感觉。比如说吧,豆腐可以做成麻辣豆腐,也可以做成臭豆腐。可是,不同的地方的人未必都喜欢这两种豆腐。四川的朋友可能更喜欢辣豆腐,江浙的人就可能对臭豆腐更喜欢一些。那么,这种情况应该怎么用设计模式表达呢?cppview plaincopy1.typedefstruct_Tofu2.3.inttype;4.void(*eat)(struct_Visitor*pVisitor,struct_Tofu*pTofu);5.Tofu;6.7.typedefstruct_Visitor8.9.intregion;10.void(*process
5、)(struct_Tofu*pTofu,struct_Visitor*pVisitor);11.Visitor; 就是这样一个豆腐,eat的时候就要做不同的判断了。cppview plaincopy1.voideat(struct_Visitor*pVisitor,struct_Tofu*pTofu)2.3.assert(NULL!=pVisitor&NULL!=pTofu);4.5.pVisitor-process(pTofu,pVisitor);6. 既然eat的操作最后还是靠不同的visitor来处理了,那么下面就该定义process函数了。cppview plaincopy1.void
6、process(struct_Tofu*pTofu,struct_Visitor*pVisitor)2.3.assert(NULL!=pTofu&NULL!=pVisitor);4.5.if(pTofu-type=SPICY_FOOD&pVisitor-region=WEST|6.pTofu-type=STRONG_SMELL_FOOD&pVisitor-region=EAST)7.8.printf(Ilikethisfood!n);9.return;10.11.12.printf(Ihatethisfood!n);13.三、C语言和设计模式(状态模式) 状态模式是协议交互中使用得比较多的模式
7、。比如说,在不同的协议中,都会存在启动、保持、中止等基本状态。那么怎么灵活地转变这些状态就是我们需要考虑的事情。假设现在有一个state,cppview plaincopy1.typedefstruct_State2.3.void(*process)();4.struct_State*(*change_state)();5.6.State; 说明一下,这里定义了两个变量,分别process函数和change_state函数。其中proces函数就是普通的数据操作,cppview plaincopy1.voidnormal_process()2.3.printf(normalprocess!n)
8、;4. change_state函数本质上就是确定下一个状态是什么。cppview plaincopy1.struct_State*change_state()2.3.State*pNextState=NULL;4.5.pNextState=(struct_State*)malloc(sizeof(struct_State);6.assert(NULL!=pNextState);7.8.pNextState-process=next_process;9.pNextState-change_state=next_change_state;10.returnpNextState;11. 所以,在c
9、ontext中,应该有一个state变量,还应该有一个state变换函数。cppview plaincopy1.typedefstruct_Context2.3.State*pState;4.void(*change)(struct_Context*pContext);5.6.Context;7.8.voidcontext_change(struct_Context*pContext)9.10.State*pPre;11.assert(NULL!=pContext);12.13.pPre=pContext-pState;14.pContext-pState=pPre-changeState()
10、;15.free(pPre);16.return;17.四、C语言和设计模式(命令模式)命令模式的目的主要是为了把命令者和执行者分开。老规矩,举个范例吧。假设李老板是一家公司的头儿,他现在让他的秘书王小姐去送一封信。王小姐当然不会自己亲自把信送到目的地,她会把信交给邮局来完成整个投递的全过程。现在,我们就对投递者、命令、发令者分别作出定义。 首先定义post的相关数据。cppview plaincopy1.typedefstruct_Post2.3.void(*do)(struct_Post*pPost);4.Post; Post完成了实际的投递工作,那么命令呢?cppview plainco
11、py1.typedefstruct_Command2.3.void*pData;4.void(*exe)(struct_Command*pCommand);5.6.Command;7.8.voidpost_exe(struct_Command*pCommand)9.10.assert(NULL!=pCommand);11.12.(Post*)(pCommand-pData)-do(Post*)(pCommand-pData);13.return;14. 我们看到了Post、Command的操作,那么剩下的就是boss的定义了。cppview plaincopy1.typedefstruct_B
12、oss2.3.Command*pCommand;4.void(*call)(struct_Boss*pBoss);5.Boss;6.7.voidboss_call(struct_Boss*pBoss)8.9.assert(NULL!=pBoss);10.11.pBoss-pCommand-exe(pBoss-pCommand);12.return;13.五、C语言和设计模式(解释器模式) 解释器模式虽然听上去有些费解,但是如果用示例说明一下就不难理解了。我们知道在C语言中,关于变量的定义是这样的:一个不以数字开始的由字母、数字和下划线构成的字符串。这种形式的表达式可以用状态自动机解决,当然也可
13、以用解释器的方式解决。cppview plaincopy1.typedefstruct_Interpret2.3.inttype;4.void*(*process)(void*pData,int*type,int*result);5.6.Interpret; 上面的数据结构比较简单,但是很能说明问题。就拿变量来说吧,这里就可以定义成字母的解释器、数字解释器、下划线解释器三种形式。所以,我们可以进一步定义一下process的相关函数。cppview plaincopy1.#defineDIGITAL_TYPE12.#defineLETTER_TYPE23.#defineBOTTOM_LINE34
14、.5.void*digital_process(void*pData,int*type,int*result)6.7.UINT8*str;8.assert(NULL!=pData&NULL!=type&NULL!=result);9.10.str=(UNT8*)pData;11.while(*str=0&*str=a&*str=A&*str=a&*str=A&*str=0&*str=a&*str=A&*str=0&*strpActionHead;7.pHead-process(pHead-pData);8.pOrganizer-pActionHead=pHead-next;9.pOrganiz
15、er-number-;10.free(pHead);11.return;12.七、C语言和设计模式(观察者模式)观察者模式可能是我们在软件开发中使用得比较多的一种设计模式。为什么这么说?大家可以听我一一到来。我们知道,在windows的软件中,所有的界都是由窗口构成的。对话框是窗口,菜单是窗口,工具栏也是窗口。那么这些窗口,在很多情况下要对一些共有的信息进行处理。比如说,窗口的放大,窗口的减小等等。面对这一情况,观察者模式就是不错的一个选择。 首先,我们可以对这些共有的object进行提炼。cppview plaincopy1.typedefstruct_Object2.3.observer*
16、pObserverListMAX_BINDING_NUMBER;4.intnumber;5.6.void(*notify)(struct_Object*pObject);7.void(*add_observer)(observer*pObserver);8.void(*del_observer)(observer*pObserver);9.10.Object; 其实,我们需要定义的就是观察者本身了。就像我们前面说的一样,观察者可以是菜单、工具栏或者是子窗口等等。cppview plaincopy1.typedefstruct_Observer2.3.Object*pObject;4.5.voi
17、d(*update)(struct_Observer*pObserver);6.Observer; 紧接着,我们要做的就是在Observer创建的时候,把observer自身绑定到Object上面。cppview plaincopy1.voidbind_observer_to_object(Observer*pObserver,Object*pObject)2.3.assert(NULL!=pObserver&NULL!=pObject);4.5.pObserver-pObject=pObject;6.pObject-add_observer(pObserver);7.8.9.voidunbind_observer_from_object(Observer*pObserver,Object*pObject)10.11.assert(NULL!=pObserver&NULL!=pObject);12.13.pObject-del_observer(observer*pObserver);
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2