一、原型模式是什么?
原型模式是一种创建型设计模式,核心思想是:以一个已初始化的"原型"对象为模板,通过克隆(复制)该原型快速创建新对象,无需重复执行复杂的构造逻辑。这和家具厂的生产逻辑高度契合------工厂会先打造"标准款家具原型"(如标准尺寸的实木餐椅、基础款咖啡桌),后续生产时无需重新画图纸、开模具、调试工艺,直接克隆原型再微调细节(如换漆面颜色、加雕花装饰),既高效又能保证基础品质一致。
原型模式的核心价值在于"复用已有对象的初始状态":当创建对象需要繁琐的初始化(如读取材质参数、加载工艺配置),或需批量生产相似对象时,克隆原型比反复新建对象更高效;同时能避免多次构造导致的基础属性偏差。
二、原型模式的核心结构(对应家具生产场景)
原型模式的结构清晰,结合家具生产场景可拆解为三个核心角色,每个角色都对应工厂中的实际职能:
-
抽象原型(Abstract Prototype):定义"可克隆"接口的抽象类,相当于家具厂的"通用生产规范",明确所有家具必须具备"复制自身"的能力。它会封装家具的通用属性(如材质、尺寸、颜色)和克隆方法。
-
具体原型(Concrete Prototype):实现抽象原型接口的具体家具类,即工厂打造的"标准款原型",如"标准实木餐椅原型""基础板式书桌原型"。它们自带固定的初始状态(如餐椅宽45cm、材质为橡木),并实现具体的克隆逻辑。
-
客户端(Client):使用原型的角色,对应家具厂的"生产工人"。工人无需掌握家具的完整构造流程,只需拿到标准原型,调用克隆方法得到新家具,再根据订单需求修改个性化细节(如将餐椅漆面从原木色改成胡桃色)。
三、代码示例:家具工厂的原型模式实现
我们以家具厂最常见的"餐椅"和"书桌"为具体原型,实现原型模式。需求是:工厂已有橡木餐椅、板式书桌的标准原型,接收订单时克隆原型,快速生产个性化家具(修改颜色、添加装饰),且修改新家具不影响原原型。
3.1 第一步:定义抽象原型(可克隆家具接口)
抽象原型类需包含家具的通用属性(材质、尺寸、颜色、装饰),以及核心的克隆纯虚函数(强制子类实现),同时提供信息展示方法。
cpp
#include <iostream>
#include <string>
using namespace std;
// 抽象原型:可克隆的家具接口
class FurniturePrototype {
protected:
string material; // 材质(橡木、板式、实木等)
string size; // 尺寸(标准化描述)
string color; // 颜色(原木色、胡桃色等)
string decoration; // 装饰(无装饰、雕花、贴皮等)
public:
// 构造函数:初始化家具基础属性(原型的标准配置)
FurniturePrototype(string mat, string sz, string col)
: material(mat), size(sz), color(col), decoration("无装饰") {}
// 虚析构:确保子类对象能正确释放
virtual ~FurniturePrototype() {}
// 通用访问器和修改器(用于个性化调整)
string getColor() { return color; }
void setColor(string col) { color = col; }
string getDecoration() { return decoration; }
void setDecoration(string dec) { decoration = dec; }
string getMaterial() { return material; }
string getSize() { return size; }
// 核心:克隆接口(纯虚函数,子类必须实现)
virtual FurniturePrototype* clone() = 0;
// 显示家具完整信息(通用实现,子类可重载)
virtual void showFurnitureInfo() {
cout << "家具材质:" << material << endl;
cout << "标准尺寸:" << size << endl;
cout << "外观颜色:" << color << endl;
cout << "装饰细节:" << decoration << endl;
cout << "-------------------------" << endl;
}
};
3.2 第二步:实现具体原型(标准款家具)
分别实现"标准橡木餐椅"和"基础板式书桌"两个具体原型,核心是重载克隆函数------通过拷贝构造自身属性,返回新的家具对象。这里采用"深拷贝"思路(因属性为string,默认拷贝已满足深拷贝需求)。
cpp
#include <iostream>
#include <string>
using namespace std;
// 前向声明抽象原型(若单独文件需包含头文件)
class FurniturePrototype;
// 具体原型1:标准橡木餐椅
class OakDiningChair : public FurniturePrototype {
public:
// 构造函数:初始化餐椅的标准配置(原型状态)
OakDiningChair()
// 调用父类构造,设定橡木材质、45*45*85cm标准尺寸、原木色
: FurniturePrototype("优质橡木", "45cm*45cm*85cm", "原木色") {}
// 实现克隆接口:创建自身的拷贝
virtual FurniturePrototype* clone() override {
// 拷贝构造当前对象,返回新的餐椅实例
return new OakDiningChair(*this);
}
// 重载信息展示(增加家具类型标识)
virtual void showFurnitureInfo() override {
cout << "【标准橡木餐椅】" << endl;
FurniturePrototype::showFurnitureInfo();
}
};
// 具体原型2:基础板式书桌
class BoardDesk : public FurniturePrototype {
public:
// 构造函数:初始化书桌的标准配置(原型状态)
BoardDesk()
// 调用父类构造,设定环保板式、120*60*75cm标准尺寸、白色
: FurniturePrototype("环保板式", "120cm*60cm*75cm", "白色") {}
// 实现克隆接口:创建自身的拷贝
virtual FurniturePrototype* clone() override {
return new BoardDesk(*this);
}
// 重载信息展示(增加家具类型标识)
virtual void showFurnitureInfo() override {
cout << "【基础板式书桌】" << endl;
FurniturePrototype::showFurnitureInfo();
}
};
3.3 第三步:客户端调用(家具厂生产流程)
客户端模拟工人操作:先获取工厂的标准原型,克隆得到新家具后,根据订单需求修改个性化参数(颜色、装饰),最终输出家具信息。整个过程无需新建原型,仅通过克隆实现快速生产。
cpp
#include <iostream>
using namespace std;
// 客户端:家具厂生产逻辑
int main() {
// 1. 工厂初始化标准原型(仅需创建一次,可重复克隆)
FurniturePrototype* standardChair = new OakDiningChair();
FurniturePrototype* standardDesk = new BoardDesk();
// 2. 订单1:生产2把胡桃色雕花餐椅(克隆原型+个性化修改)
cout << "=== 订单1:胡桃色雕花橡木餐椅(2把) ===" << endl;
FurniturePrototype* chair1 = standardChair->clone();
chair1->setColor("胡桃色");
chair1->setDecoration("椅背雕花");
chair1->showFurnitureInfo();
FurniturePrototype* chair2 = standardChair->clone();
chair2->setColor("胡桃色");
chair2->setDecoration("椅背雕花");
chair2->showFurnitureInfo();
// 3. 订单2:生产1张灰色贴皮书桌(克隆原型+个性化修改)
cout << "=== 订单2:灰色贴皮板式书桌(1张) ===" << endl;
FurniturePrototype* desk1 = standardDesk->clone();
desk1->setColor("深灰色");
desk1->setDecoration("桌面木纹贴皮");
desk1->showFurnitureInfo();
// 4. 验证原原型未被修改(核心:克隆不影响原型状态)
cout << "=== 验证标准原型状态 ===" << endl;
cout << "标准餐椅状态:" << endl;
standardChair->showFurnitureInfo();
cout << "标准书桌状态:" << endl;
standardDesk->showFurnitureInfo();
// 释放资源
delete standardChair;
delete standardDesk;
delete chair1;
delete chair2;
delete desk1;
return 0;
}
四、原型模式的关键要点(结合家具场景总结)
-
克隆的核心是"属性拷贝":若家具包含指针等复杂属性(如"配件清单"动态数组),需实现深拷贝,避免克隆对象与原型共享资源;若仅为基础类型(string、int),默认浅拷贝即可。
-
原型需初始化完整状态:标准原型的初始属性(如材质、尺寸)必须明确,否则克隆的新家具会存在基础缺陷,就像工厂原型尺寸错误会导致所有克隆产品不合格。
-
适用场景匹配:当家具生产中"构造成本高"(如定制款家具需反复调试参数)或"批量生产相似产品"(如同一户型的家具套装)时,原型模式优势最明显;若每次都需全新设计(如艺术定制家具),则不适用。