外观、装饰和组合模式(结构型设计模式)的 C++ 代码示例模板。

前言

外观、装饰和组合模式(结构型设计模式)的 C++ 代码示例模板。


代码仓库


外观模式(Facade)

结构

  • 子系统类(多个)(被管理者)
  • 外观类(管理者)
  • 外观类 封装 子系统对象
  • 外观类的方案方法 调用子系统对象的方法 搭配成不同方案 (不同对象、方法(内容)和时序/步骤等)
  • 客户端只知道外观类,不知道子系统类

代码

#include <iostream>

using std::cout;
using std::endl;

// 子系统类(多个)(被管理者)
// 子系统 A 类
class SubsystemA
{
public:
    void func_A()
    {
        cout << "func_A()" << endl;
    }
};

// 子系统 B 类
class SubsystemB
{
public:
    void func_B()
    {
        cout << "func_B()" << endl;
    }
};

// 外观类(管理者)
class Facade
{
public:
    Facade() : subsystem_A(), subsystem_B() {} // 子系统类的 默认构造方法初始化 子系统对象

    // 外观类的方案方法 调用子系统对象的方法 搭配成不同方案(不同对象、方法(内容)和时序/步骤等)
    // 方案1
    void option1()
    {
        subsystem_A.func_A();
        subsystem_B.func_B();
    }

    // 方案2
    void option2()
    {
        subsystem_B.func_B();
        subsystem_A.func_A();
    }

    // 方案n...

private:
    // 外观类 封装 子系统对象
    SubsystemA subsystem_A;
    SubsystemB subsystem_B;
};

// 客户端
int main()
{
    // 客户端只知道外观类,不知道子系统类
    Facade facade;

    facade.option1(); // 使用方案1
    facade.option2(); // 使用方案2

    return 0;
}
/*
输出:
func_A()
func_B()
func_B()
func_A()
*/

装饰模式(Decorator)

结构

  • 抽象组件类
  • 具体组件类(被装饰者)
  • 抽象装饰类
  • 具体装饰类(装饰者)
  • 抽象装饰类 继承 抽象组件类
  • 抽象装饰类 封装 抽象组件指针(实际上会指向一个具体组件对象)(装饰者包装被装饰者)
  • 抽象装饰类 重写 抽象组件类的方法
  • 形式上 调用 装饰类的方法
  • 实际上 调用 抽象组件指针/具体组件对象的方法(原本内容) + 装饰类的额外内容(装饰内容) (重点理解)
  • 具体装饰类 重写 抽象组件类的方法
  • 形式上 调用 装饰类的方法
  • 实际上 调用 抽象组件指针/具体组件对象的方法(原本内容) + 装饰类的额外内容(装饰内容) (重点理解)
  • 注意浅拷贝和深拷贝问题:相同组件不同装饰,需要浅拷贝
  • 注意同一组件不同装饰的重复析构问题

代码

#include <iostream>

using std::cout;
using std::endl;

// 抽象组件类
class AbstractComponent
{
public:
    virtual ~AbstractComponent() = default;

    virtual void func() = 0;
};

// 具体组件类(被装饰者)
class ConcreteComponent : public AbstractComponent
{
public:
    void func() override
    {
        cout << "component" << endl;
    }
};

// 抽象装饰类
// 抽象装饰类 继承 抽象组件类
class AbstractDecorator : public AbstractComponent
{
public:
    // 注意浅拷贝和深拷贝问题:相同组件不同组件,需要浅拷贝
    AbstractDecorator(AbstractComponent *abstract_component) : abstract_component(abstract_component) {}
    virtual ~AbstractDecorator() override
    {
        delete this->abstract_component;
    }

    // 抽象装饰类 重写 抽象组件类的方法
    // 形式上 调用 装饰类的方法
    // 实际上 调用 抽象组件指针/具体组件对象的方法(原本内容) + 装饰类的额外内容(装饰内容)(重点理解)
    void func() override
    {
        if (this->abstract_component != nullptr)
        {
            this->abstract_component->func();
        }
    }

private:
    // 抽象装饰类 封装 抽象组件指针(实际上会指向一个具体组件对象)(装饰者包装被装饰者)
    AbstractComponent *abstract_component;
};

// 具体装饰 A 类
class ConcreteDecoratorA : public AbstractDecorator
{
public:
    ConcreteDecoratorA(AbstractComponent *abstract_component) : AbstractDecorator(abstract_component) {}

    // 具体装饰类 重写 抽象组件类的方法
    void func() override // 形式上 调用 装饰类的方法
    {
        AbstractDecorator::func();            // 实际上 调用 抽象组件指针/具体组件对象的方法(原本内容)
        cout << "ConcreteDecoratorA" << endl; // + 装饰类的额外内容(装饰内容)(重点理解)
    }
};

// 具体装饰 B 类
class ConcreteDecoratorB : public AbstractDecorator
{
public:
    ConcreteDecoratorB(AbstractComponent *abstract_component) : AbstractDecorator(abstract_component) {}

    // 具体装饰类 重写 抽象组件类的方法
    void func() override // 形式上 调用 装饰类的方法
    {
        AbstractDecorator::func();            // 实际上 调用 抽象组件指针/具体组件对象的方法(原本内容)
        cout << "ConcreteDecoratorB" << endl; // + 装饰类的额外内容(装饰内容)(重点理解)
    }
};

// 客户端
int main()
{
    // 注意同一组件不同装饰的重复析构问题
    // AbstractComponent *abstract_component = new ConcreteComponent(); // 抽象组件指针/具体组件对象

    // // 抽象组件指针/具体装饰 A 对象装饰组件
    // AbstractComponent *concrete_decorator_A = new ConcreteDecoratorA(abstract_component);
    // concrete_decorator_A->func(); // 形式上 调用 装饰类的方法

    // AbstractComponent *concrete_decorator_B = new ConcreteDecoratorB(abstract_component);
    // concrete_decorator_B->func();

    // delete concrete_decorator_B; // 第一次 delete abstract_component
    // delete concrete_decorator_A; // 第二次 delete abstract_component
    // delete abstract_component;   // 第三次 delete abstract_component

    // 解决1:使用智能指针,shared_ptr<>
    // 解决2:手动实现引用计数机制
    // 解决3:程序结束自动释放全部
    // 解决4:使用相同组件的不同副本
    // 解决5:使用不同组件
    // 解决n...
    // 使用解决5
    AbstractComponent *abstract_component_a = new ConcreteComponent(); // 抽象组件指针/具体组件对象
    // 抽象组件指针/具体装饰 A 对象装饰组件
    AbstractComponent *concrete_decorator_A = new ConcreteDecoratorA(abstract_component_a);
    concrete_decorator_A->func(); // 形式上 调用 装饰类的方法
    delete concrete_decorator_A;  // 第一次 delete abstract_component
    // delete abstract_component_a;  // 第二次 delete abstract_component

    AbstractComponent *abstract_component_b = new ConcreteComponent();
    AbstractComponent *concrete_decorator_B = new ConcreteDecoratorB(abstract_component_b);
    concrete_decorator_B->func();
    delete concrete_decorator_B;

    return 0;
}

组合模式(Composite)

结构

  • 组件类
  • 树叶类(树的叶节点)
  • 树枝类(树的非叶节点)
  • 树叶类 继承 组件类,重写 虚方法
  • 树枝类 继承 组件类,封装 组件类的集合(实际上包含零个或多个树叶对象或树枝对象),重写 虚方法
  • 客户端 以相同的方式处理/一致地使用 简单和复杂元素/单个和组合对象

类型

  • 透明方式:组件类有管理子对象的方法(添加组件方法和删除组件方法等),树枝类和叶子类的行为一致;但叶子类继承和实现该些方法没有意义,违反接口隔离原则(ISP)
  • 安全方式:组件类没有管理子对象的方法,树枝类有管理子对象的方法

代码(安全方式)

// 安全方式:组件类没有管理子对象的方法,树枝类有管理子对象的方法
#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::vector;

// 组件类
class Component
{
public:
    virtual ~Component() {}

    virtual void func() = 0;
};

// 树叶类(树的叶节点)
// 树叶类 继承 组件类,重写 虚方法
class Leaf : public Component
{
public:
    Leaf(int value) : value(value) {}

    void func() override
    {
        cout << "Leaf: " << this->value << endl;

        return;
    }

private:
    int value;
};

// 树枝类(树的非叶节点)
// 树枝类 继承 组件类,封装 组件类的集合(实际上包含零个或多个树叶对象或树枝对象),重写 虚方法
class Branch : public Component
{
public:
    Branch() : component_vec() {} // vector<> 的 默认构造方法初始化 属性
    ~Branch()
    {
        for (Component *component : this->component_vec)
        {
            delete component;
        }
    }

    void add(Component *component)
    {
        this->component_vec.push_back(component);
    }

    void func() override
    {
        cout << "Branch: " << endl;
        for (Component *component : this->component_vec)
        {
            component->func();
        }
    }

private:
    vector<Component *> component_vec;
};

// 客户端

int main()
{
    // 树叶
    Leaf *leaf_1 = new Leaf(10);
    Leaf *leaf_2 = new Leaf(20);
    Leaf *leaf_3 = new Leaf(30);

    // 树枝
    Branch *branch_1 = new Branch();
    branch_1->add(leaf_1);
    branch_1->add(leaf_2);

    // 树枝/根
    Branch *branch_2 = new Branch();
    branch_2->add(leaf_3);
    branch_2->add(branch_1);

    // 客户端 以相同的方式处理/一致地使用 简单和复杂元素/单个和组合对象
    leaf_2->func();
    cout << endl;
    branch_2->func();

    delete branch_2; // 会自动递归 delete branch_1、leaf_2、leaf_1 和 leaf_3

    return 0;
}
/*
Leaf: 20

Branch:
Leaf: 30
Branch:
Leaf: 10
Leaf: 20
*/

总结

外观、装饰和组合模式(结构型设计模式)的 C++ 代码示例模板。


参考资料


作者的话

  • 感谢参考资料的作者/博主
  • 作者:夜悊
  • 版权所有,转载请注明出处,谢谢~
  • 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
  • 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
  • 文章在认识上有错误的地方, 敬请批评指正
  • 望读者们都能有所收获

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值