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

相关推荐
ZouZou老师2 小时前
C++设计模式之桥接模式:以家具生产为例
c++·设计模式·桥接模式
呱呱巨基2 小时前
Linux 进程概念
linux·c++·笔记·学习
liulilittle2 小时前
C++ 浮点数封装。
linux·服务器·开发语言·前端·网络·数据库·c++
ZouZou老师3 小时前
C++设计模式之组合模式:以家具生产为例
c++·设计模式·组合模式
yong15858553433 小时前
2. Linux C++ muduo 库学习——原子变量操作头文件
linux·c++·学习
小小8程序员3 小时前
STL 库(C++ Standard Template Library)全面介绍
java·开发语言·c++
老王熬夜敲代码4 小时前
C++中的atomic
开发语言·c++·笔记·面试
龚礼鹏5 小时前
Android应用程序 c/c++ 崩溃排查流程
c语言·开发语言·c++
REDcker6 小时前
JS 与 C++ 语言绑定技术详解
开发语言·javascript·c++