
模式动机
原型模式的简单程度仅次于单例模式和迭代器模式。正是由于简 单,使用的场景才非常地多。它的主要功能是用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
简单来说呢,就是利用当前结构体来复制出一个新的结构体。就比如说有一份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的方法创建一个对象,然后由工厂方法提供给调用者。