原型模式: Specify the kinds of objects to create using a prototypical instance,and create new objects by copying this prototype.(用原型实例指定创建对象的种类, 并且通过拷贝这些原型创建新的对象。 )
UML图:
代码实现:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 原型接口
typedef struct {void* (*clone)(void*);
} Prototype;// 具体原型类
typedef struct {Prototype prototype;char* name;int age;
} ConcretePrototype;void* ConcretePrototype_clone(void* obj) {ConcretePrototype* self = (ConcretePrototype*)obj;ConcretePrototype* clone = malloc(sizeof(ConcretePrototype));memcpy(clone, self, sizeof(ConcretePrototype));clone->name = malloc(strlen(self->name) + 1);strcpy(clone->name, self->name);return clone;
}ConcretePrototype createConcretePrototype(char* name, int age) {ConcretePrototype prototype;prototype.prototype.clone = ConcretePrototype_clone;prototype.name = malloc(strlen(name) + 1);strcpy(prototype.name, name);prototype.age = age;return prototype;
}int main() {ConcretePrototype prototype = createConcretePrototype("Alice", 25);ConcretePrototype* clone = prototype.prototype.clone(&prototype);printf("Name: %s, Age: %d\n", clone->name, clone->age);free(clone->name);free(clone);return 0;
}
在上面的示例代码中,首先定义了原型接口Prototype
,其中包含了一个克隆函数指针。然后定义了具体原型类ConcretePrototype
,它实现了原型接口中的克隆函数。
接着在main
函数中,创建了一个具体原型对象prototype
,然后通过克隆函数创建了一个新的对象clone
,最后输出了新对象的属性。
原型模式的优点:
-
可以动态克隆对象,减少了对象创建过程中的时间和资源消耗。
-
可以隐藏对象创建细节,使用户无需关心对象的创建方式。
-
可以为使用者提供更加灵活的对象创建方式。
原型模式的缺点:
-
需要深度复制对象的所有属性,包括引用类型的属性,否则会出现浅拷贝导致的问题。
-
如果对象有循环引用,则需要特殊处理。
适用场景:
-
对象的创建过程比较复杂或耗时,需要缩短对象创建时间。
-
对象的创建方式比较固定,但是需要某些属性进行个性化设置。
-
对象的构造函数是私有的,不能直接调用,但又需要复制该对象。