找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 4035|回复: 2

C语言和设计模式(享元模式)

[复制链接]
发表于 2011-12-31 19:47:47 | 显示全部楼层 |阅读模式
【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】


    享元模式看上去有点玄乎,但是其实也没有那么复杂。我们还是用示例说话。比如说,大家在使用电脑的使用应该少不了使用WORD软件。使用WORD呢, 那就少不了设置模板。什么模板呢,比如说标题的模板,正文的模板等等。这些模板呢,又包括很多的内容。哪些方面呢,比如说字体、标号、字距、行距、大小等等。
  1. typedef struct _Font
  2. {
  3.     int type;
  4.     int sequence;
  5.     int gap;
  6.     int lineDistance;
  7.     void (*operate)(struct _Font* pFont);
  8. }Font;
复制代码
   上面的Font表示了各种Font的模板形式。所以,下面的方法就是定制一个FontFactory的结构。
  1. typedef struct _FontFactory
  2. {
  3.     Font** ppFont;
  4.     int number;
  5.     int size;
  6.     Font* GetFont(struct _FontFactory* pFontFactory, int type, int sequence, int gap, int lineDistance);
  7. }FontFactory;
复制代码

    这里的GetFont即使对当前的Font进行判断,如果Font存在,那么返回;否则创建一个新的Font模式。
  1. Font* GetFont(struct _FontFactory* pFontFactory, int type, int sequence, int gap, int lineDistance)
  2. {
  3.     int index;
  4.     Font* pFont;
  5.     Font* ppFont;
  6.     if(NULL == pFontFactory)
  7.         return NULL;
  8.     for(index = 0; index < pFontFactory->number; index++)
  9.     {
  10.         if(type != pFontFactory->ppFont[index]->type)
  11.             continue;
  12.         if(sequence != pFontFactory->ppFont[index]->sequence)
  13.             continue;
  14.         if(gap != pFontFactory->ppFont[index]->gap)
  15.             continue;
  16.         if(lineDistance != pFontFactory->ppFont[index]->lineDistance)
  17.              continue;
  18.         return pFontFactory->ppFont[index];
  19.     }   
  20.     pFont = (Font*)malloc(sizeof(Font));
  21.     assert(NULL != pFont);
  22.     pFont->type = type;
  23.     pFont->sequence = sequence;
  24.     pFont->gap = gap;
  25.     pFont->lineDistance = lineDistance;
  26.     if(pFontFactory-> number < pFontFactory->size)
  27.     {
  28.         pFontFactory->ppFont[index] = pFont;
  29.         pFontFactory->number ++;
  30.         return pFont;
  31.     }
  32.     ppFont = (Font**)malloc(sizeof(Font*) * pFontFactory->size * 2);
  33.     assert(NULL != ppFont);
  34.     memmove(ppFont, pFontFacoty->ppFont, pFontFactory->size);
  35.     free(pFontFactory->ppFont);
  36.     pFontFactory->size *= 2;
  37.     pFontFactory->number ++;
  38.     ppFontFactory->ppFont = ppFont;
  39.     return pFont;      
  40. }
复制代码



作者:feixiaoxing 发表于2011-12-26 22:26:49 原文链接
 楼主| 发表于 2011-12-31 19:48:23 | 显示全部楼层
C语言和设计模式(装饰模式)平凡的程序员|feixiaoxing
【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】


    装饰模式是比较好玩,也比较有意义。其实就我个人看来,它和责任链还是蛮像的。只不过一个是比较判断,一个是迭代处理。装饰模式就是那种迭代处理的模式,关键在哪呢?我们可以看看数据结构。
  1. typedef struct _Object
  2. {
  3.     struct _Object* prev;
  4.     void (*decorate)(struct _Object* pObject);
  5. }Object;
复制代码
   装饰模式最经典的地方就是把pObject这个值放在了数据结构里面。当然,装饰模式的奥妙还不仅仅在这个地方,还有一个地方就是迭代处理。我们可以自己随便写一个decorate函数试试看,
  1. void decorate(struct _Object* pObeject)
  2. {
  3.     assert(NULL != pObject);
  4.     if(NULL != pObject->prev)
  5.         pObject->prev->decorate(pObject->prev);
  6.     printf("normal decorate!\n");
  7. }
复制代码
   所以,装饰模式的最重要的两个方面就体现在:prev参数和decorate迭代处理。
 楼主| 发表于 2011-12-31 19:49:11 | 显示全部楼层
C语言和设计模式(适配器模式)


【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】

    现在的生活当中,我们离不开各种电子工具。什么笔记本电脑、手机、mp4啊,都离不开充电。既然是充电,那么就需要用到充电器。其实从根本上来说,充电器就是一个个普通的适配器。什么叫适配器呢,就是把220v、50hz的交流电压编程5~12v的直流电压。充电器就干了这么一件事情。
    那么,这样的一个充电适配器,我们应该怎么用c++描述呢?   
  1. class voltage_12v
  2. {
  3. public:
  4.     voltage_12v() {}
  5.     virtual ~voltage_12v() {}
  6.     virtual void request() {}
  7. };
  8. class v220_to_v12
  9. {
  10. public:
  11.     v220_to_v12() {}
  12.     ~v220_to_v12() {}
  13.     void voltage_transform_process() {}
  14. };
  15. class adapter: public voltage_12v
  16. {
  17.     v220_to_v12* pAdaptee;
  18. public:
  19.     adapter() {}
  20.     ~adapter() {}
  21.     void request()
  22.     {
  23.         pAdaptee->voltage_transform_process();
  24.     }  
  25. };
复制代码
    通过上面的代码,我们其实可以这样理解。类voltage_12v表示我们的最终目的就是为了获得一个12v的直流电压。当然获得12v可以有很多的方法,利用适配器转换仅仅是其中的一个方法。adapter表示适配器,它自己不能实现220v到12v的转换工作,所以需要调用类v220_to_v12的转换函数。所以,我们利用adapter获得12v的过程,其实就是调用v220_to_v12函数的过程。
    不过,既然我们的主题是用c语言来编写适配器模式,那么我们就要实现最初的目标。这其实也不难,关键一步就是定义一个Adapter的数据结构。然后把所有的Adapter工作都由Adaptee来做,就是这么简单。不知我说明白了没有?
  1. typdef struct _Adaptee
  2. {
  3.     void (*real_process)(struct _Adaptee* pAdaptee);
  4. }Adaptee;
  5. typedef struct _Adapter
  6. {
  7.     void* pAdaptee;
  8.     void (*transform_process)(struct _Adapter* pAdapter);
  9. }Adapter;
复制代码
作者:feixiaoxing 发表于2011-12-28 20:15:28 原文链接
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-5-2 10:34 , Processed in 0.022688 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表