外观、装饰和组合模式(结构型设计模式)的 C++ 代码示例模板。
2023-12-20 13:46:13
    		前言
外观、装饰和组合模式(结构型设计模式)的 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++ 代码示例模板。
参考资料
作者的话
- 感谢参考资料的作者/博主
 - 作者:夜悊
 - 版权所有,转载请注明出处,谢谢~
 - 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
 - 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
 - 文章在认识上有错误的地方, 敬请批评指正
 - 望读者们都能有所收获
 
    			文章来源:https://blog.csdn.net/m0_62083249/article/details/135093683
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
    	本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!