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组件装饰(如给按钮添加边框、背景、图标)等场景中也被广泛应用。

相关推荐
像素猎人4 分钟前
map<数据类型,数据类型> mp和unordered_map<数据类型,数据类型> ump的讲解,蓝桥杯OJ4567最大数目
c++·算法·蓝桥杯·stl·map
张涛酱1074564 分钟前
Agent Skills 深入解析:构建可插拔的智能体知识体系
spring·设计模式·ai编程
Kel5 分钟前
CrewAI v1.14.2 双模式架构深度剖析:当角色协作遇上事件驱动
人工智能·设计模式·架构
沐雪轻挽萤16 分钟前
1. C++17新特性-序章
java·c++·算法
郝学胜-神的一滴24 分钟前
从链表到二叉树:树形结构的入门与核心性质解析
数据结构·c++·python·算法·链表
玖釉-31 分钟前
深入解析 meshoptimizer:基于 meshopt_computeSphereBounds 的层级包围球构建与 DAG 优化
c++·算法·图形渲染
wuxinyan12331 分钟前
Java面试题48:一文深入了解java设计模式
java·设计模式·面试
CoderMeijun32 分钟前
C++ 单例模式:饿汉模式与懒汉模式
c++·单例模式·设计模式·饿汉模式·懒汉模式
电商API&Tina39 分钟前
淘宝 / 京东关键词搜索 API 接入与实战用途教程|从 0 到 1 搭建电商选品 / 比价 / 爬虫替代系统
java·开发语言·数据库·c++·python·spring
初圣魔门首席弟子1 小时前
Doxygen 文档注释详细介绍(含实际案例)
c++