一、装饰器模式核心概念
装饰器模式是一种结构型设计模式,其核心思想是在不改变原有类结构和逻辑的前提下,通过动态地给对象添加额外职责(装饰)的方式,实现功能的灵活扩展。这种模式避免了使用继承扩展功能时可能出现的"类爆炸"问题,让每个装饰功能都成为独立的可复用组件。
以家具生产为例:基础家具(如椅子、桌子)是核心产品,而刷漆、雕花、包边等工艺则是附加的装饰功能。如果用继承实现,会出现"红漆雕花椅子""清漆包边桌子"等无数组合类;而用装饰器模式,基础家具和每个装饰工艺都是独立类,可根据需求动态组合,极大提升灵活性。
二、家具生产场景下的装饰器模式角色
-
抽象组件(Component):定义家具的核心接口,规范所有家具(包括基础家具和装饰后家具)的统一行为。对应场景中的"家具"抽象类,包含展示家具信息的核心方法。
-
具体组件(Concrete Component):抽象组件的具体实现,即未经过装饰的基础家具。对应场景中的"椅子""桌子"等具体家具类。
-
抽象装饰器(Decorator):继承抽象组件,同时持有抽象组件的引用,是所有装饰器的基类。它既遵循家具的接口规范,又能包裹其他家具(基础家具或已装饰家具),为添加装饰功能提供基础结构。对应场景中的"家具装饰器"抽象类。
-
具体装饰器(Concrete Decorator):抽象装饰器的具体实现,负责实现特定的装饰功能。对应场景中的"刷漆装饰器""雕花装饰器""包边装饰器"等。
三、完整代码实现(家具装饰场景)
cpp
#include <iostream>
#include <string>
using namespace std;
// 1. 抽象组件:家具
class Furniture {
public:
virtual ~Furniture() {}
// 核心方法:展示家具信息(包含基础属性和装饰效果)
virtual string showInfo() const = 0;
};
// 2. 具体组件:基础家具 - 椅子
class Chair : public Furniture {
public:
string showInfo() const override {
return "基础椅子(材质:实木)";
}
};
// 2. 具体组件:基础家具 - 桌子
class Table : public Furniture {
public:
string showInfo() const override {
return "基础桌子(材质:实木)";
}
};
// 3. 抽象装饰器:家具装饰器
class FurnitureDecorator : public Furniture {
protected:
// 持有一个家具对象的引用(可包裹基础家具或已装饰的家具)
Furniture* furniture;
public:
// 构造函数:传入要装饰的家具
FurnitureDecorator(Furniture* fur) : furniture(fur) {}
~FurnitureDecorator() {
// 释放被装饰的家具对象(此处简化为直接释放,实际项目需考虑内存管理策略)
delete furniture;
}
// 委托给被装饰的家具实现基础展示,后续具体装饰器再追加效果
string showInfo() const override {
return furniture->showInfo();
}
};
// 4. 具体装饰器:刷漆装饰
class PaintDecorator : public FurnitureDecorator {
private:
// 装饰属性:漆的颜色
string color;
public:
// 构造函数:传入要装饰的家具和漆的颜色
PaintDecorator(Furniture* fur, const string& col) : FurnitureDecorator(fur), color(col) {}
// 重写展示方法:在基础信息后追加刷漆效果
string showInfo() const override {
return FurnitureDecorator::showInfo() + ",装饰:刷" + color + "漆";
}
};
// 4. 具体装饰器:雕花装饰
class CarvingDecorator : public FurnitureDecorator {
private:
// 装饰属性:雕花样式
string style;
public:
CarvingDecorator(Furniture* fur, const string& sty) : FurnitureDecorator(fur), style(sty) {}
string showInfo() const override {
return FurnitureDecorator::showInfo() + ",装饰:" + style + "雕花";
}
};
// 4. 具体装饰器:包边装饰
class EdgeWrappingDecorator : public FurnitureDecorator {
private:
// 装饰属性:包边材质
string material;
public:
EdgeWrappingDecorator(Furniture* fur, const string& mat) : FurnitureDecorator(fur), material(mat) {}
string showInfo() const override {
return FurnitureDecorator::showInfo() + ",装饰:" + material + "包边";
}
};
// 测试代码
int main() {
// 场景1:基础椅子 → 刷红色漆 → 加牡丹雕花
Furniture* redPeonyChair = new CarvingDecorator(
new PaintDecorator(new Chair(), "红色"),
"牡丹"
);
cout << "产品1:" << redPeonyChair->showInfo() << endl;
delete redPeonyChair;
// 场景2:基础桌子 → 刷清漆 → 加胡桃木包边
Furniture* clearVarnishTable = new EdgeWrappingDecorator(
new PaintDecorator(new Table(), "清"),
"胡桃木"
);
cout << "产品2:" << clearVarnishTable->showInfo() << endl;
delete clearVarnishTable;
// 场景3:基础椅子 → 直接加龙凤雕花(不刷漆)
Furniture* dragonPhoenixChair = new CarvingDecorator(new Chair(), "龙凤");
cout << "产品3:" << dragonPhoenixChair->showInfo() << endl;
delete dragonPhoenixChair;
return 0;
}
四、代码解析与运行效果
-
抽象组件Furniture :定义了
showInfo()纯虚函数,是所有家具和装饰器的统一接口,保证了装饰后对象与基础对象的兼容性。 -
具体组件Chair/Table:实现了基础家具的信息展示,是装饰器模式的"装饰目标",无需关注任何装饰逻辑。
-
抽象装饰器FurnitureDecorator :继承Furniture并持有Furniture指针,通过构造函数接收待装饰对象,
showInfo()方法委托给被装饰对象,为具体装饰器提供了"包裹"基础对象的能力。 -
具体装饰器PaintDecorator等 :继承抽象装饰器,新增了装饰属性(如颜色、样式),并重写
showInfo()方法,在基础对象信息的基础上追加装饰效果,实现了功能的动态扩展。
五、装饰器模式在家具生产场景的优势
-
灵活扩展,避免类爆炸:若用继承实现"红漆雕花椅子",需创建Chair→RedPaintChair→RedPaintPeonyChair等多层继承类,而装饰器模式通过组合实现,新增装饰仅需新增装饰器类。
-
动态组合装饰效果:可在运行时根据需求组合不同装饰(如客户临时要求将"清漆桌子"改为"红漆雕花桌子"),无需修改原有对象结构。
-
单一职责原则:基础家具类仅负责基础属性和行为,每个装饰器仅负责一种装饰功能,便于维护和复用(如"刷漆装饰器"可同时用于椅子、桌子等多种家具)。
六、适用场景总结
当需要为对象动态添加或移除职责、避免用继承导致类数量激增、或需要组合多种职责时,装饰器模式是最优选择。除家具生产外,在IO流处理(如C++的istream与ifstream、istringstream的组合)、GUI组件装饰(如给按钮添加边框、背景、图标)等场景中也被广泛应用。