C++设计模式——装饰器模式

装饰器设计模式

概念

装饰器设计模式,是C++设计模式中的一种。它是一种结构型设计模式,允许向现有对象动态地添加新功能,同时又不改变其结构。这种模式是通过创建一个包装对象来实现的,也就是说,实际对象被包装在装饰器类的实例中。装饰器类实现了与实际对象相同的接口,并且可以添加额外的行为。

应用场景

装饰器模式的核心是功能扩展,使用装饰器模式可以透明且动态地扩展类的功能。在不改变原有类结构的基础上,扩展新的功能。

优点

降低代码之间的耦合性,提高了灵活性,具有更好的扩展性。

示例

下面是三个简单的C++实现装饰器模式的示例,仅供理解该设计模式。

示例一

代码实现

cpp 复制代码
#include <iostream>
using namespace std;

// 接口
class Component {
public:
    virtual void operation() = 0;
};

// 具体组件
class ConcreteComponent : public Component {
public:
    virtual void operation() {
        cout << "具体对象的操作" << endl;
    }
};

// 装饰器
class Decorator : public Component {
protected:
    Component* component;
public:
    void setComponent(Component* component) {
        this->component = component;
    }
    virtual void operation() {
        if (component != nullptr) {
            component->operation();
        }
    }
};

// 具体装饰器
class ConcreteDecoratorA : public Decorator {
public:
    virtual void operation() {
        Decorator::operation(); // 调用父类的operation
        addedBehavior();
    }
    void addedBehavior() {
        cout << "为具体构件A扩展的操作" << endl;
    }
};

class ConcreteDecoratorB : public Decorator {
public:
    virtual void operation() {
        Decorator::operation(); // 调用父类的operation
        addedBehavior();
    }
    void addedBehavior() {
        cout << "为具体构件B扩展的操作" << endl;
    }
};

int main() {
    Component* component = new ConcreteComponent();
    Decorator* decorator1 = new ConcreteDecoratorA();
    Decorator* decorator2 = new ConcreteDecoratorB();

    decorator1->setComponent(component);
    decorator2->setComponent(decorator1);
    decorator2->operation();

    delete decorator2;
    delete decorator1;
    delete component;

    return 0;
}

在这个示例中,Component 是接口,定义了操作的抽象方法。ConcreteComponent 是具体的对象。Decorator 是装饰器类,继承自 Component,并包含一个指向 Component 对象的指针。ConcreteDecoratorA 和 ConcreteDecoratorB 是具体的装饰器类,继承自 Decorator,并在 operation 方法中扩展了额外的行为。

在 main 函数中,我们创建了一个具体的对象 component,然后通过 ConcreteDecoratorA 和 ConcreteDecoratorB 对其进行装饰,最终调用 decorator2 的 operation 方法。

运行结果

示例二

使用装饰器模式实现一个计算图形面积的程序,并添加日志记录功能。

代码实现

cpp 复制代码
#include <iostream>  
#include <string>  
  
// 定义一个接口类  
class Shape {  
public:  
    virtual double getArea() = 0;  
};  
  
// 实现接口类的具体类  
class Rectangle : public Shape {  
private:  
    double width;  
    double height;  
public:  
    Rectangle(double w, double h) : width(w), height(h) {}  
    double getArea() override {  
        std::cout << "Rectangle::getArea() - calculating area..." << std::endl;  
        return width * height;  
    }  
};  
  
// 实现一个装饰器类,用于给具体类添加额外的功能  
class ShapeDecorator : public Shape {  
protected:  
    Shape* decoratedShape; // 保存一个指向被装饰对象的指针  
public:  
    ShapeDecorator(Shape* shape) : decoratedShape(shape) {}  
    double getArea() override {  
        return decoratedShape->getArea(); // 调用被装饰对象的操作  
    }  
};  
  
// 具体的装饰器类,添加日志记录功能  
class LoggingShapeDecorator : public ShapeDecorator {  
private:  
    std::string message;  
public:  
    LoggingShapeDecorator(Shape* shape, std::string msg) : ShapeDecorator(shape), message(msg) {}  
    double getArea() override {  
        std::cout << message << " - starting calculation..." << std::endl;  
        double result = decoratedShape->getArea(); // 调用被装饰对象的操作  
        std::cout << message << " - calculation complete." << std::endl;  
        return result;  
    }  
};  
  
int main() {  
    Shape* rectangle = new Rectangle(5, 10); // 创建一个具体对象  
    Shape* loggingRectangle = new LoggingShapeDecorator(rectangle, "Rectangle::getArea()"); // 创建一个被装饰的对象,并添加日志记录功能  
    std::cout << "Area: " << rectangle->getArea() << std::endl; // 输出 "Rectangle::getArea() - calculating area..." 和 "Area: 50"  
    std::cout << "Area (with logging): " << loggingRectangle->getArea() << std::endl; // 输出 "Rectangle::getArea() - starting calculation...", "Rectangle::getArea() - calculating area...", "Rectangle::getArea() - calculation complete." 和 "Area (with logging): 50"  
    delete rectangle; // 释放内存  
    delete loggingRectangle; // 释放内存  
    return 0;  
}

运行结果

示例三

使用装饰器模式编写一个绘图功能,并模拟添加一些额外的功能。

实现代码

cpp 复制代码
#include <iostream>  
#include <string>  
  
// 定义一个接口类  
class Shape {  
public:  
    virtual void draw() = 0;  
};  
  
// 实现接口类的具体类  
class Rectangle : public Shape {  
public:  
    void draw() override {  
        std::cout << "Rectangle::draw()" << std::endl;  
    }  
};  
  
// 实现一个装饰器类,用于给具体类添加额外的功能  
class ShapeDecorator : public Shape {  
protected:  
    Shape* decoratedShape; // 保存一个指向被装饰对象的指针  
public:  
    ShapeDecorator(Shape* shape) : decoratedShape(shape) {}  
    void draw() override {  
        decoratedShape->draw(); // 调用被装饰对象的操作  
    }  
};  
  
// 具体的装饰器类,添加新的功能  
class RedShapeDecorator : public ShapeDecorator {  
public:  
    RedShapeDecorator(Shape* shape) : ShapeDecorator(shape) {}  
    void draw() override {  
        decoratedShape->draw(); // 调用被装饰对象的操作  
        std::cout << "RedShapeDecorator::draw() - draw red border" << std::endl;  
    }  
};  
  
int main() {  
    Shape* rectangle = new Rectangle(); // 创建一个具体对象  
    Shape* redRectangle = new RedShapeDecorator(new Rectangle()); // 创建一个被装饰的对象  
    rectangle->draw(); // 输出 "Rectangle::draw()"  
    redRectangle->draw(); // 输出 "Rectangle::draw()" 和 "RedShapeDecorator::draw() - draw red border"  
    delete rectangle; // 释放内存  
    delete redRectangle; // 释放内存  
    return 0;  
}

运行结果

总结

装饰器设计模式其本质上还是使用多态的原理,提供了一种可扩展功能的设计模式。

相关推荐
ephemerals__5 分钟前
【c++丨STL】list模拟实现(附源码)
开发语言·c++·list
Microsoft Word20 分钟前
c++基础语法
开发语言·c++·算法
一只小小汤圆1 小时前
opencascade源码学习之BRepOffsetAPI包 -BRepOffsetAPI_DraftAngle
c++·学习·opencascade
legend_jz1 小时前
【Linux】线程控制
linux·服务器·开发语言·c++·笔记·学习·学习方法
嘿BRE1 小时前
【C++】几个基本容器的模拟实现(string,vector,list,stack,queue,priority_queue)
c++
ö Constancy2 小时前
c++ 笔记
开发语言·c++
fengbizhe2 小时前
笔试-笔记2
c++·笔记
徐霞客3202 小时前
Qt入门1——认识Qt的几个常用头文件和常用函数
开发语言·c++·笔记·qt
fpcc2 小时前
redis6.0之后的多线程版本的问题
c++·redis
螺旋天光极锐斩空闪壹式!3 小时前
自制游戏:监狱逃亡
c++·游戏