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
,最后输出了新对象的属性。
原型模式的优点:
-
可以动态克隆对象,减少了对象创建过程中的时间和资源消耗。
-
可以隐藏对象创建细节,使用户无需关心对象的创建方式。
-
可以为使用者提供更加灵活的对象创建方式。
原型模式的缺点:
-
需要深度复制对象的所有属性,包括引用类型的属性,否则会出现浅拷贝导致的问题。
-
如果对象有循环引用,则需要特殊处理。
适用场景:
-
对象的创建过程比较复杂或耗时,需要缩短对象创建时间。
-
对象的创建方式比较固定,但是需要某些属性进行个性化设置。
-
对象的构造函数是私有的,不能直接调用,但又需要复制该对象。