C语言设计模式.docx
《C语言设计模式.docx》由会员分享,可在线阅读,更多相关《C语言设计模式.docx(26页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、精选优质文档-倾情为你奉上目录1.C语言设计模式(开篇) 关于软件设计方面的书很多,比如重构,比如设计模式。至于软件开发方式,那就更多了,什么极限编程、精益方法、敏捷方法。随着时间的推移,很多的方法又会被重新提出来。 其实,就我个人看来,不管什么方法都离不开人。一个人写不出二叉树,你怎么让他写?敏捷吗?你写一行,我写一行。还是迭代?写三行,删掉两行,再写三行。项目的成功是偶然的,但是项目的失败却有很多原因,管理混乱、需求混乱、设计低劣、代码质量差、测试不到位等等。就软件企业而言,没有比优秀的文化和出色的企业人才更重要的了。 从软件设计层面来说,一般来说主要包括三个方面: (1)软件的设计受众,
2、是小孩子、老人、女性,还是专业人士等等; (2)软件的基本设计原则,以人为本、模块分离、层次清晰、简约至上、适用为先、抽象基本业务等等; (3)软件编写模式,比如装饰模式、责任链、单件模式等等。 从某种意义上说,设计思想构成了软件的主题。软件原则是我们在开发中的必须遵循的准绳。软件编写模式是开发过程中的重要经验总结。灵活运用设计模式,一方面利于我们编写高质量的代码,另一方面也方便我们对代码进行维护。毕竟对于广大的软件开发者来说,软件的维护时间要比软件编写的时间要多得多。编写过程中,难免要有新的需求,要和别的模块打交道,要对已有的代码进行复用,那么这时候设计模式就派上了用场。我们讨论的主题其实就
3、是设计模式。 讲到设计模式,人们首先想到的语言就是c#或者是java,最不济也是c+,一般来说没有人会考虑到c语言。其实,我认为设计模式就是一种基本思想,过度美化或者神化其实没有必要。其实阅读过linux kernel的朋友都知道,linux虽然自身支持很多的文件系统,但是linux自身很好地把这些系统的基本操作都抽象出来了,成为了基本的虚拟文件系统。 举个例子来说,现在让你写一个音乐播放器,但是要支持的文件格式很多,什么ogg,wav,mp3啊,统统要支持。这时候,你会怎么编写呢?如果用C+语言,你可能会这么写。class music_file HANDLE hFile;public: vo
4、id music_file() virtual music_file() virtual void read_file() virtual void play() virtual void stop() virtual void back() virtual void front() virtual void up() virtual void down() ; 其实,你想想看,如果用C语言能够完成相同的抽象操作,那不是效果一样的吗?typedef struct _music_file HANDLE hFile; void (*read_file)(struct _music_file* pM
5、usicFile); void (*play)(struct _music_file* pMusicFile); void (*stop)(struct _music_file* pMusicFile); void (*back)(struct _music_file* pMusicFile); void (*front)(struct _music_file* pMusicFile); void (*down)(struct _music_file* pMusicFile); void (*up)(struct _music_file* pMusicFile); music_file;当然,
6、上面的例子比较简单,但是也能说明一些问题。写这篇文章的目的一是希望和朋友们共同学习模式的相关内容,另一方面也希望朋友们能够活学活用,既不要迷信权威,也不要妄自菲薄。只要付出努力,付出汗水,肯定会有收获的。有些大环境你改变不了,那就从改变自己开始。万丈高楼平地起,一步一个脚印才能真真实实学到东西。如果盲目崇拜,言必google、微软、apple,那么除了带来几个唾沫星,还能有什么受用呢?无非白费了口舌而已。 希望和大家共勉。2.C语言和设计模式(继承、封装、多态)记得还在我们大学C+第一门课的时候,老师就告诉我们说,C+是一门面向对象的语言。C+有三个最重要的特点,即继承、封装、多态。等到后来随
7、着编码的增多和工作经验的积累,我也慢慢明白了面向对象的含义。可是,等我工作以后,使用的编程语言更多的是C语言,这时候我又想能不能把C语言变成面向对象的语言呢?等到后来通过思考和实践,我发现其实C语言也是可以面向对象的,也是可以应用设计模式的,关键就在于如何实现面向对象语言的三个重要属性。2.1继承性typedef struct _parent int data_parent;Parent;typedef struct _Child struct _parent parent; int data_child;Child;在设计C语言继承性的时候,我们需要做的就是把基础数据放在继承的结构的首位置即
8、可。这样,不管是数据的访问、数据的强转、数据的访问都不会有什么问题。2.2封装性struct _Data;typedef void (*process)(struct _Data* pData);typedef struct _Data int value; process pProcess; Data;封装性的意义在于,函数和数据是绑在一起的,数据和数据是绑在一起的。这样,我们就可以通过简单的一个结构指针访问到所有的数据,遍历所有的函数。封装性,这是类拥有的属性,当然也是数据结构体拥有的属性。2.3多态3.单件模式有过面试经验的朋友,或者对设计模式有点熟悉的朋友,都会对单件模式不陌生。对很多
9、面试官而言,单件模式更是他们面试的保留项目。其实,我倒认为,单件模式算不上什么设计模式。最多也就是个技巧。单件模式要是用C+写,一般这么写。#include #include class objectpublic: static class object* pObject; static object* create_new_object() if(NULL != pObject)return pObject;pObject = new object();assert(NULL != pObject);return pObject; private: object() object() ;cl
10、ass object* object:pObject = NULL;单件模式的技巧就在于类的构造函数是一个私有的函数。但是类的构造函数又是必须创建的?怎么办呢?那就只有动用static函数了。我们看到static里面调用了构造函数,就是这么简单。int main(int argc, char* argv)object* pGlobal = object:create_new_object();return 1;4.工厂模式工厂模式是比较简单,也是比较好用的一种方式。根本上说,工厂模式的目的就根据不同的要求输出不同的产品。比如说吧,有一个生产鞋子的工厂,它能生产皮鞋,也能生产胶鞋。如果用代码设计
11、,应该怎么做呢?typedef struct _Shoe int type; void (*print_shoe)(struct _Shoe*);Shoe; 就像上面说的,现在有胶鞋,那也有皮鞋,我们该怎么做呢?void print_leather_shoe(struct _Shoe* pShoe) assert(NULL != pShoe); printf(This is a leather show!n);void print_rubber_shoe(struct _Shoe* pShoe) assert(NULL != pShoe); printf(This is a rubber sh
12、oe!n);所以,对于一个工厂来说,创建什么样的鞋子,就看我们输入的参数是什么?至于结果,那都是一样的。#define LEATHER_TYPE 0x01#define RUBBER_TYPE 0x02Shoe* manufacture_new_shoe(int type) assert(LEATHER_TYPE = type | RUBBER_TYPE = type); Shoe* pShoe = (Shoe*)malloc(sizeof(Shoe); assert(NULL != pShoe); memset(pShoe, 0, sizeof(Shoe); if(LEATHER_TYPE
13、= type) pShoe-type = LEATHER_TYPE; pShoe-print_shoe = print_leather_shoe; else pShoe-type = RUBBER_TYPE; pShoe-print_shoe = print_rubber_shoe; return pShoe;5.抽象工厂模式前面我们写过的工厂模式实际上是对产品的抽象。对于不同的用户需求,我们可以给予不同的产品,而且这些产品的接口都是一致的。而抽象工厂呢?顾名思义,就是说我们的工厂是不一定的。怎么理解呢,举个例子。 假设有两个水果店都在卖水果,都卖苹果和葡萄。其中一个水果店买白苹果和白葡萄,另
14、外一个水果店卖红苹果和红葡萄。所以说,对于水果店而言,尽管都在卖水果,但是两个店卖的品种不一样。 既然水果不一样,那我们先定义水果。typedef struct _Apple void (*print_apple)();Apple;typedef struct _Grape void (*print_grape)();Grape;上面分别对苹果和葡萄进行了抽象,当然它们的具体函数也是不一样的。void print_white_apple() printf(white apple!n);void print_red_apple() printf(red apple!n);void print_w
15、hite_grape() printf(white grape!n);void print_red_grape() printf(red grape!n);完成了水果函数的定义。下面就该定义工厂了,和水果一样,我们也需要对工厂进行抽象处理。typedef struct _FruitShop Apple* (*sell_apple)(); Grape * (*sell_grape)();FruitShop; 所以,对于卖白苹果、白葡萄的水果店就该这样设计了,红苹果、红葡萄的水果店亦是如此。Apple* sell_white_apple() Apple* pApple = (Apple*) mal
16、loc(sizeof(Apple); assert(NULL != pApple); pApple-print_apple = print_white_apple; return pApple;Grape* sell_white_grape() Grape* pGrape = (Grape*) malloc(sizeof(Grape); assert(NULL != pGrape); pGrape-print_grape = print_white_grape; return pGrape;这样,基本的框架就算搭建完成的,以后创建工厂的时候,FruitShop* create_fruit_sh
17、op(int color) FruitShop* pFruitShop = (FruitShop*) malloc(sizeof(FruitShop); assert(NULL != pFruitShop); if(WHITE = color) pFruitShop-sell_apple = sell_white_apple; pFruitShop-sell_grape = sell_white_grape; else pFruitShop-sell_apple = sell_red_apple; pFruitShop-sell_grape = sell_red_grape; return p
18、FruitShop;6.访问者模式不知不觉当中,我们就到了最后一种设计模式,即访问者模式。访问者模式,听上去复杂一些。但是,这种模式用简单的一句话说,就是不同的人对不同的事物有不同的感觉。比如说吧,豆腐可以做成麻辣豆腐,也可以做成臭豆腐。可是,不同的地方的人未必都喜欢这两种豆腐。四川的朋友可能更喜欢辣豆腐,江浙的人就可能对臭豆腐更喜欢一些。那么,这种情况应该怎么用设计模式表达呢?typedef struct _Tofu int type; void (*eat)(struct _Visitor* pVisitor, struct _Tofu* pTofu);Tofu;typedef struc
19、t _Visitor int region; void (*process)(struct _Tofu* pTofu, struct _Visitor* pVisitor);Visitor;7.状态模式 状态模式是协议交互中使用得比较多的模式。比如说,在不同的协议中,都会存在启动、保持、中止等基本状态。那么怎么灵活地转变这些状态就是我们需要考虑的事情。假设现在有一个state, 说明一下,这里定义了两个变量,分别process函数和change_state函数。其中proces函数就是普通的数据操作,void normal_process() printf(normal process!n);
20、 change_state函数本质上就是确定下一个状态是什么。所以,在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-chan
21、geState(); free(pPre); return; 8.命令模式 命令模式的目的主要是为了把命令者和执行者分开。老规矩,举个范例吧。假设李老板是一家公司的头儿,他现在让他的秘书王小姐去送一封信。王小姐当然不会自己亲自把信送到目的地,她会把信交给邮局来完成整个投递的全过程。现在,我们就对投递者、命令、发令者分别作出定义。首先定义post的相关数据。typedef struct _Post void (*do)(struct _Post* pPost); Post;Post完成了实际的投递工作,那么命令呢?void post_exe(struct _Command* pCommand)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 设计 模式
限制150内