C++设计模式之装饰器模式:以家具生产为例

一、装饰器模式核心概念

装饰器模式是一种结构型设计模式,其核心思想是在不改变原有类结构和逻辑的前提下,通过动态地给对象添加额外职责(装饰)的方式,实现功能的灵活扩展。这种模式避免了使用继承扩展功能时可能出现的"类爆炸"问题,让每个装饰功能都成为独立的可复用组件。

以家具生产为例:基础家具(如椅子、桌子)是核心产品,而刷漆、雕花、包边等工艺则是附加的装饰功能。如果用继承实现,会出现"红漆雕花椅子""清漆包边桌子"等无数组合类;而用装饰器模式,基础家具和每个装饰工艺都是独立类,可根据需求动态组合,极大提升灵活性。

二、家具生产场景下的装饰器模式角色

  1. 抽象组件(Component):定义家具的核心接口,规范所有家具(包括基础家具和装饰后家具)的统一行为。对应场景中的"家具"抽象类,包含展示家具信息的核心方法。

  2. 具体组件(Concrete Component):抽象组件的具体实现,即未经过装饰的基础家具。对应场景中的"椅子""桌子"等具体家具类。

  3. 抽象装饰器(Decorator):继承抽象组件,同时持有抽象组件的引用,是所有装饰器的基类。它既遵循家具的接口规范,又能包裹其他家具(基础家具或已装饰家具),为添加装饰功能提供基础结构。对应场景中的"家具装饰器"抽象类。

  4. 具体装饰器(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()方法,在基础对象信息的基础上追加装饰效果,实现了功能的动态扩展。

五、装饰器模式在家具生产场景的优势

  1. 灵活扩展,避免类爆炸:若用继承实现"红漆雕花椅子",需创建Chair→RedPaintChair→RedPaintPeonyChair等多层继承类,而装饰器模式通过组合实现,新增装饰仅需新增装饰器类。

  2. 动态组合装饰效果:可在运行时根据需求组合不同装饰(如客户临时要求将"清漆桌子"改为"红漆雕花桌子"),无需修改原有对象结构。

  3. 单一职责原则:基础家具类仅负责基础属性和行为,每个装饰器仅负责一种装饰功能,便于维护和复用(如"刷漆装饰器"可同时用于椅子、桌子等多种家具)。

六、适用场景总结

当需要为对象动态添加或移除职责、避免用继承导致类数量激增、或需要组合多种职责时,装饰器模式是最优选择。除家具生产外,在IO流处理(如C++的istreamifstreamistringstream的组合)、GUI组件装饰(如给按钮添加边框、背景、图标)等场景中也被广泛应用。

相关推荐
爱装代码的小瓶子9 分钟前
【c++进阶】c++11的魔法:从模板到可变模板.
android·开发语言·c++
曼巴UE513 分钟前
UE GamePlayTag
c++·ue5·ue
山风wind35 分钟前
设计模式-责任链模式:让请求在链条中流动直到被处理
设计模式·责任链模式
慕容青峰35 分钟前
【加拿大计算机竞赛 CCO 小行星采矿】题解
c++·算法·sublime text
Ghost-Silver39 分钟前
2025年度总结
开发语言·数据结构·c++·算法
yyy(十一月限定版)1 小时前
C++基础
java·开发语言·c++
invicinble1 小时前
设计模式全局预览,以及为什么会
设计模式
Ralph_Y2 小时前
C++数据库操作
开发语言·数据库·c++
酬勤-人间道2 小时前
CAD 曲线切割 3D 曲面:坡面 / 开挖模型的开挖 - 填埋精准计算解决方案
c++·计算机·cad·布尔计算·曲线切割·工业级解决方案·岩体
不会写代码的里奇2 小时前
从零开发基于DeepSeek的端侧离线大模型语音助手:全流程指南
c++·后端·音视频