(二)结构型模式:5、装饰器模式(Decorator Pattern)(C++实例)

目录

1、装饰器模式(Decorator Pattern)含义

2、装饰器模式的UML图学习

3、装饰器模式的应用场景

4、装饰器模式的优缺点

5、C++实现装饰器模式的简单实例


1、装饰器模式(Decorator Pattern)含义

装饰模式(Decorator),动态地给一个对象添加一些额外地职责,就增加功能来说,装饰模式比生成子类更为灵活【DP】

装饰模式(Decorator Pattern)是一种结构型设计模式,它允许你在不改变现有对象结构的情况下,动态地向对象添加额外的功能。

装饰模式通过将对象包装在装饰器类中,实现了透明地扩展对象的能力。

2、装饰器模式的UML图学习

 组成元素:

(1)Component是定义一个对象接口,可以给这些对象动态地添加职责;

(2)ConcreteComponent是定义了一个具体地对象,也可以给这个对象添加一些职责;

(3)Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的。至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能【DPE】

3、装饰器模式的应用场景

(1)IO流操作:在IO流中,可以使用装饰器模式来添加缓冲、加密、压缩等功能,而无需修改原始的IO类。

(2)GUI组件:在图形用户界面中,可以使用装饰器模式来为组件添加边框、滚动条、阴影等外观效果。

(3)日志记录:可以使用装饰器模式来为日志记录器添加时间戳、日志级别等额外信息。

(4)权限控制:可以使用装饰器模式来为对象添加权限验证、身份认证等功能。

总之,装饰器模式适用于需要动态地为对象添加功能,并且希望保持对象接口的一致性的场景。

它提供了一种灵活、可扩展和可维护的方式来处理对象功能的变化和组合。

4、装饰器模式的优缺点

(1)优点:

1)动态地为对象添加功能:装饰器模式允许在运行时动态地为对象添加额外的功能,而无需修改原始对象的结构。这对于需要灵活地扩展对象功能的情况非常有用。

2)避免使用子类进行扩展:通过使用装饰器模式,可以避免创建大量的子类来实现不同组合的功能。相反,可以通过组合和堆叠装饰器来实现各种功能组合,从而更好地管理和维护代码。

3)对象功能的透明性:装饰器模式使得客户端可以透明地使用被装饰对象和装饰后的对象,无需关心具体对象的类型。这样可以简化客户端代码,并且使得代码更加清晰易懂。

4)单一职责原则:装饰器模式可以将功能划分到不同的装饰器中,每个装饰器只负责一个特定的功能,符合单一职责原则。这样可以使得代码更加可维护和可扩展。

(2)缺点:

1)增加复杂性:使用装饰器模式会引入更多的类和对象,从而增加了系统的设计复杂性。这可能会导致代码结构变得复杂,不易理解和维护。

2)多层装饰影响性能:当使用多个装饰器进行功能堆叠时,可能会对性能产生一定的影响。每个装饰器都会增加额外的处理逻辑,可能会导致性能下降。

3)可能造成对象过度膨胀:如果使用过多的装饰器或者装饰器的组合方式不合理,可能会导致对象过度膨胀,使得系统资源消耗增加。

总结:尽管装饰器模式存在一些缺点,但它仍然是一种强大且常用的设计模式,特别适用于需要动态地为对象添加功能的场景。

在使用装饰器模式时,需要根据具体的需求和系统设计来权衡其优缺点,并确保合理地应用该模式。

5、C++实现装饰器模式的简单实例

#include <iostream>

// 抽象组件
class Component 
{
public:
    virtual void operation() const = 0;
};

// 具体组件
class ConcreteComponent : public Component 
{
public:
    void operation() const override 
    {
        std::cout << "ConcreteComponent operation" << std::endl;
    }
};

// 抽象装饰器
class Decorator : public Component 
{
protected:
    Component* component;

public:
    Decorator(Component* component) : component(component) {}

    void operation() const override 
    {
        if (component != nullptr) 
        {
            component->operation();
        }
    }
};

// 具体装饰器
class ConcreteDecorator : public Decorator 
{
public:
    ConcreteDecorator(Component* component) : Decorator(component) {}

    void operation() const override 
    {
        Decorator::operation();
        additionalOperation();
    }

    void additionalOperation() const 
    {
        std::cout << "Additional operation" << std::endl;
    }
};

int main()
 {
    // 创建具体组件对象
    Component* component = new ConcreteComponent();

    // 使用具体装饰器包装具体组件对象
    Component* decoratedComponent = new ConcreteDecorator(component);

    // 调用装饰后的操作方法
    decoratedComponent->operation();

    delete decoratedComponent;
    delete component;

    return 0;
}

在上述示例中,我们定义了一个 Component 接口作为抽象组件,其中包含了一个 operation 方法。ConcreteComponent 类表示具体组件,实现了抽象组件的接口。

Decorator 类是抽象装饰器,继承自 Component,并且持有一个 Component 的引用。它通过该引用调用被装饰对象的方法。

ConcreteDecorator 类是具体装饰器,继承自 Decorator,并实现了具体的装饰逻辑。在 operation 方法中,它先调用父类的 operation 方法,然后执行额外的操作。

在 main 函数中,我们创建了一个具体组件对象 component,并使用具体装饰器 ConcreteDecorator 对其进行包装。最后,调用装饰后的操作方法 decoratedComponent->operation(),会先执行具体组件的操作方法,然后执行具体装饰器的额外操作。

运行以上代码,输出将会是:

ConcreteComponent operation

Additional operation

可以看到,通过装饰模式,我们在不改变具体组件对象的情况下,动态地为其添加了额外的功能。

猜你喜欢

转载自blog.csdn.net/bigger_belief/article/details/132301984
今日推荐