创建型模式:④原型模式(Prototype)
c语言写法
核心思想
通过 “拷贝原型实例” 创建新对象(避免重复初始化,适合复杂对象创建)。
关键要点
1.核心是 拷贝接口(clone 函数),必须实现 深拷贝(避免指针共享导致的问题)。
2.优势:创建复杂对象时,无需重复执行初始化逻辑(如读取配置、网络请求),直接拷贝原型即可。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 原型接口(抽象原型)
typedef struct Prototype {
char content[128]; // 原型属性
// 拷贝接口(核心:深拷贝,避免浅拷贝问题)
struct Prototype* (*clone)(struct Prototype*);
void (*destroy)(struct Prototype*);
} Prototype;
// 深拷贝实现(关键:字符串需单独分配内存)
Prototype* prototype_clone(Prototype* self) {
Prototype* clone = (Prototype*)malloc(sizeof(Prototype));
strncpy(clone->content, self->content, sizeof(clone->content));
clone->clone = prototype_clone; // 复用拷贝逻辑
clone->destroy = free;
return clone;
}
// 创建原型实例(原型模板)
Prototype* create_prototype(const char* init_content) {
Prototype* proto = (Prototype*)malloc(sizeof(Prototype));
strncpy(proto->content, init_content, sizeof(proto->content));
proto->clone = prototype_clone;
proto->destroy = free;
return proto;
}
// 测试代码
int main() {
// 1. 创建原型(模板实例)
Prototype* proto = create_prototype("初始文档:设计模式笔记");
printf("原型内容:%s\n", proto->content);
// 2. 拷贝原型创建新对象(无需重新初始化)
Prototype* clone1 = proto->clone(proto);
strcat(clone1->content, " - 工厂方法模式"); // 修改拷贝对象的属性
printf("拷贝1内容:%s\n", clone1->content);
// 3. 再次拷贝,创建另一个新对象
Prototype* clone2 = proto->clone(proto);
strcat(clone2->content, " - 抽象工厂模式");
printf("拷贝2内容:%s\n", clone2->content);
// 4. 验证原型与拷贝对象相互独立
printf("原型是否被修改:%s\n", strcmp(proto->content, "初始文档:设计模式笔记") == 0 ? "否" : "是");
// 5. 资源释放
proto->destroy(proto);
clone1->destroy(clone1);
clone2->destroy(clone2);
return 0;
}
c++语言写法
核心思想
通过 虚拷贝接口(clone) 实现对象的深拷贝,客户端通过拷贝原型实例创建新对象,避免重复初始化。
关键要点
1.虚 clone 接口:Clone() 是纯虚函数,子类必须实现深拷贝逻辑(如果有动态分配的成员,需手动复制,如 char* 需 strcpy 新内存)。
2.深拷贝保障:std::string 自带深拷贝,若成员是指针(如 char*),需在 Clone() 中手动分配内存并复制数据,避免浅拷贝导致的野指针。
3.效率优势:复杂对象(如需要读取文件、网络请求初始化)通过拷贝原型创建,比重新初始化更高效。
#include <iostream>
#include <string>
#include <memory>
#include <cstring>
// -------------------------- 抽象原型 --------------------------
class Prototype {
public:
virtual ~Prototype() = default;
// 纯虚clone接口:子类必须实现深拷贝
virtual std::unique_ptr<Prototype> Clone() const = 0;
virtual void ShowContent() const = 0;
};
// -------------------------- 具体原型:文档 --------------------------
class Document : public Prototype {
public:
Document(std::string content) : content_(std::move(content)) {}
// 深拷贝实现(C++11移动语义优化)
std::unique_ptr<Prototype> Clone() const override {
// 拷贝自身的所有属性(如果有动态成员,需手动分配内存)
return std::make_unique<Document>(this->content_);
}
void ShowContent() const override {
std::cout << "文档内容:" << content_ << std::endl;
}
// 修改内容(示例)
void AppendContent(const std::string& append) {
content_ += append;
}
private:
std::string content_; // std::string自动处理深拷贝
};
// 测试代码
int main() {
// 1. 创建原型实例(模板)
std::unique_ptr<Prototype> proto = std::make_unique<Document>("初始文档:设计模式笔记");
proto->ShowContent();
// 2. 拷贝原型创建新对象(深拷贝)
std::unique_ptr<Prototype> clone1 = proto->Clone();
clone1->AppendContent(" - 工厂方法模式");
clone1->ShowContent();
// 3. 再次拷贝原型(不影响原型和其他拷贝)
std::unique_ptr<Prototype> clone2 = proto->Clone();
clone2->AppendContent(" - 抽象工厂模式");
clone2->ShowContent();
// 4. 验证原型未被修改
std::cout << "\n原型是否被修改:";
proto->ShowContent();
return 0;
}
979

被折叠的 条评论
为什么被折叠?



