C语言设计模式--原型模式
模式动机
原型模式的简单程度仅次于单例模式和迭代器模式。正是由于简 单,使用的场景才非常地多。它的主要功能是用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
简单来说呢,就是利用当前结构体来复制出一个新的结构体。就比如说有一份word文档,它本身是一个对象,但是我可以利用这份文档通过不断地进行复制粘贴,从而得到很多新的一模一样的文档,每一份文档都是一个新的对象。如下图
举个例子,我现在要去投简历面试,然后需要事先准备了3份完全一样的简历。
传统代码实现:
#include <stdio.h> typedef struct Resume { char* name; char* sex; int age; }s_resume; void main() { s_resume *info1,*info2,*info3; /*构造第一份简历*/ info1 = (s_resume*)malloc(sizeof(s_resume)); info1->name = "皮特"; info1->sex = "男"; info1->age = 20; printf("这是%s的简历,性别为%s,年龄%d\n",info1->name,info1->sex,info1->age); /*构造第二份简历*/ info2 = (s_resume*)malloc(sizeof(s_resume)); info2->name = "皮特"; info2->sex = "男"; info2->age = 20; printf("这是%s的简历,性别为%s,年龄%d\n",info2->name,info2->sex,info2->age); /*构造第三份简历*/ info3 = (s_resume*)malloc(sizeof(s_resume)); info3->name = "皮特"; info3->sex = "男"; info3->age = 20; printf("这是%s的简历,性别为%s,年龄%d\n",info3->name,info3->sex,info3->age); } }
代码可以直接复制粘贴在菜鸟 C 在线工具运行(https://c.runoob.com/compile/11)中查看运行结果。结果如下:
这是皮特的简历,性别为男,年龄20
这是皮特的简历,性别为男,年龄20
这是皮特的简历,性别为男,年龄20
我们看下这样做法的弊端:
三份简历需要三次同样的手动初始化,非常麻烦,如果需要几十分、上百份,代码非常臃肿丑陋。
如果一旦简历的内容发生了变化,那么需要逐份去修改,效率极低。
解决方案
使用原型模式,增加一个复制接口,充分利用现有的对象来复制其他的对象,从而减化对象的初始化过程。代码注释非常清晰地展示了思路过程。
原型模式代码实现:
#include <stdio.h> typedef struct Resume { char* name; char* sex; int age; /*增加复制接口*/ struct Resume* (*copy) (struct Resume* pData); }s_resume; /*复制接口实现*/ struct Resume* Resume_copy(struct Resume* pData) { s_resume* pResult = (s_resume*)malloc(sizeof(s_resume)); memmove(pResult, pData, sizeof(s_resume)); return pResult; }; void main() { s_resume *info1,*info2,*info3; /*构造第一份简历*/ info1 = (s_resume*)malloc(sizeof(s_resume)); info1->name = "皮特"; info1->sex = "男"; info1->age = 20; info1->copy = Resume_copy; printf("这是%s的简历,性别为%s,年龄%d\n",info1->name,info1->sex,info1->age); /*构造第二份简历*/ info2 = info1->copy(info1); printf("这是%s的简历,性别为%s,年龄%d\n",info2->name,info2->sex,info2->age); /*构造第三份简历*/ info3 = info1->copy(info1); printf("这是%s的简历,性别为%s,年龄%d\n",info3->name,info3->sex,info3->age); }
代码可以直接复制粘贴在菜鸟 C 在线工具运行(https://c.runoob.com/compile/11)中查看运行结果。结果如下:
这是皮特的简历,性别为男,年龄20
这是皮特的简历,性别为男,年龄20
这是皮特的简历,性别为男,年龄20
原型模式性能优良,通过内存二进制流的拷贝,要比频繁手动地初始化一个对象开销低很多。尤其是要在产生大量的对象时,原型模式可以更好地体现其优点。
不过在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过copy的方法创建一个对象,然后由工厂方法提供给调用者。