【C++】—— 装饰器模式

简介: 【C++】—— 装饰器模式



(一)什么是装饰器模式

装饰模式(Decorator Pattern),也被称为包装模式,是一种通过对客户端透明的方式来扩展对象功能的设计模式,它提供了一种替代继承关系的方案。装饰模式通过将要添加的附加功能放在独立的类中,并让这个类包含要装饰的对象,实现了在运行时动态地给对象添加功能的能力。

在装饰模式中,抽象构件定义了对象的接口,具体构件是被装饰的对象,装饰者持有一个构件对象的引用,并定义与抽象构件一致的接口。装饰者可以在调用构建对象的方法前后添加额外的行为,从而扩展对象的功能。

通过使用装饰模式,我们可以灵活地在运行时动态地给对象添加功能,而无需改变原有类的结构。客户端可以按照需要选择、按顺序使用不同的装饰者来包装对象,从而达到组合各种功能的目的。这种方式实现了功能的扩展和复用,同时也避免了使用继承带来的静态特性和多个子类的维护问题。


(二)为什么要使用装饰器模式

  1. 装饰模式可以动态的给一个对象添加一 些额外的职责。
  2. 就增加功能来说,此模式比生成子类更为灵活,通过子类继承的方式,但是如果后续继续增加功能的话,便要继续继承现有的类,如此就会使继承的层次越来越深,不利与代码的维护和可读性。
  3. 故最好的方式便是通过装饰者模式来完成。

(三)装饰器模式的实现步奏

  • 提供一个抽象组件类:抽象被装饰者的行为
  • 提供一个或多个具体组件类:被装饰者的行为具体实现
  • 提供一个抽象装饰器类:抽象组件指针与抽象组件一致接口
  • 提供一个具体的装饰器类:为具体组件附加责任


(四)代码示例

场景

  • 对于一些职场人士在出席一些重要场合的时候,大部分都是西装革履的。因此,我在这里就模拟男士穿衣的场景

首先,定义一个抽象基类Boy代表男生;

class Boy {
public:
    virtual void wearClothes() = 0;
};

接下来,创建具体的男生类;

class ConcreteBoy : public Boy {
public:
    void wearClothes() override {
        cout << "首先穿上打底衫" << endl;
    }
};

然后,定义装饰器基类;

class Decorator : public Boy {
protected:
    Boy* boy;
public:
    Decorator(Boy* b) : boy(b) {}
    virtual void wearClothes() override {
        if (boy != nullptr) {
            boy->wearClothes();
        }
    }
};

接着,创建具体的装饰器类;

//穿西装
class JacketDecorator : public Decorator {
public:
    JacketDecorator(Boy* b) : Decorator(b) {}
    void wearClothes() override {
        Decorator::wearClothes();
        cout << "紧接着穿上西服" << endl;
    }
};
//打领带
class TieDecorator : public Decorator {
public:
    TieDecorator(Boy* b) : Decorator(b) {}
    void wearClothes() override {
        Decorator::wearClothes();
        cout << "最后再打领带" << endl;
    }
};

最后,在主函数中使用这些类来展示男生穿衣服的场景;

int main() {
    Boy* boy = new TieDecorator(new JacketDecorator(new ConcreteBoy()));
    boy ->wearClothes();
    delete boy ;
    return 0;
}

(五)装饰器模式优缺点

优点

  1. 灵活性:装饰器模式允许动态地给对象添加功能,而且可以根据需要多次进行装饰,从而实现各种组合方式,使得功能扩展变得非常灵活。
  2. 开闭原则:装饰器模式符合开闭原则,可以在不修改现有代码的情况下,增加新的功能。

缺点

  1. 复杂性:装饰器模式引入了许多小的对象和类,可能会导致系统中对象数量的增加,从而增加系统的复杂性。
  2. 容易出错:由于装饰器模式允许灵活地组合对象,因此在设计时需要特别小心,以避免出现过度复杂或混乱的装饰器组合,导致难以理解和维护的问题。

总体来说,装饰器模式是一种非常灵活的设计模式,能够有效地扩展对象的功能,同时也需要在设计时注意控制复杂性,避免出现过度装饰的情况。

相关文章
|
2月前
|
设计模式 uml C++
C++中的装饰器模式:灵活地扩展功能
C++中的装饰器模式:灵活地扩展功能
35 0
|
7月前
|
设计模式 C++
[学习][笔记]设计模式(基于C/C++实现)<五>装饰器模式
[学习][笔记]设计模式(基于C/C++实现)<五>装饰器模式
|
设计模式 C++
[学习][笔记]设计模式(基于C/C++实现)<五>装饰器模式
设计模式(基于C/C++实现)<五>装饰器模式
|
1天前
|
编译器 C++
【C++】一文全解四种经典 [ 特殊类 ]的设计
【C++】一文全解四种经典 [ 特殊类 ]的设计
|
2天前
|
编译器 C语言 C++
c++初阶------类和对象(六大默认构造函数的揭破)-3
c++初阶------类和对象(六大默认构造函数的揭破)
|
2天前
|
编译器 C语言 C++
c++初阶------类和对象(六大默认构造函数的揭破)-2
c++初阶------类和对象(六大默认构造函数的揭破)
|
2天前
|
存储 编译器 C语言
c++初阶------类和对象(六大默认构造函数的揭破)-1
c++初阶------类和对象(六大默认构造函数的揭破)
|
2天前
|
存储 编译器 C语言
c++初阶-------类和对象-2
c++初阶-------类和对象
|
2天前
|
编译器 C语言 C++
c++初阶-------类和对象-1
c++初阶-------类和对象
|
3天前
|
存储 Java C++
【C++类和对象】探索static成员、友元以及内部类
【C++类和对象】探索static成员、友元以及内部类