zoukankan      html  css  js  c++  java
  • 设计模式—装饰模式的C++实现

          这是Bwar在2009年写的设计模式C++实现,代码均可编译可运行,一直存在自己的电脑里,曾经在团队技术分享中分享过,现搬到线上来。

    1. 装饰模式简述

    1.1 目的

          动态地给一个对象添加一些额外的职责。

    1.2 适用性

         (1)  在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。

         (2)  处理那些可以取消的职责。

         (3)  不能或不好采用生成子类的方法扩充职责。

    2. 装饰模式结构图

         

    • Component:定义一个对象接口,可以给这些对象动态地添加职责。
    • ConcreteComponent:定义一个对象,可以给这个对象添加一些职责。
    • Decorator:维持一个只想Component对象的指针,并定义一个与Component接口一致的接口。
    • ConcreteDecorator:向组建添加职责。

    3. 装饰模式的应用场景举例

    3.1 程序日志类

    • 文件日志类
    • 控制台日志类
    • 数据库日志类
    • 网络日志类

           使用者只调用写日志接口,对日志写到哪里,如何写并不是使用者所关心的,写日志的位置和内容变更也不关心。

          

    3.2 数据库代理类

    • MySQL数据代理
    • Oracle数据代理
    • SQLServer数据代理
    • 网络数据中转代理类

          使用者只想执行基本的数据库查询、插入、取结果操作,SQL符合规范,操作的是什么数据库,分布在哪里都不是他所关心的;即使数据库从SQLServer换成了MySQL,只要库表结构不变也不需要改代码。

         

    4.  装饰模式C++实现示例

          有两个背包:一个运动背包(平时打篮球、打羽毛球时背),一个户外背包(爬山、徒步时背),出去的时候偶尔会在背包上挂上一些挂饰。

         

    代码实现:

    Bag.hpp:

    #ifndef BAG_HPP_
    #define BAG_HPP_
    
    #include <iostream>
    
    using namespace std;
    
    class CBag
    {
    public:
        CBag(){}
        virtual ~CBag(){}
    
        virtual void Operation() = 0;
    };
    
    #endif /* BAG_HPP_ */

    SportBag.hpp:

    #ifndef SPORTBAG_HPP_
    #define SPORTBAG_HPP_
    
    #include <iostream>
    #include "Bag.hpp"
    
    class CSportBag : public CBag
    {
    public:
        CSportBag(){}
        virtual ~CSportBag(){}
    
        virtual void Operation()
        {
            cout << "Sport bag ";
        }
    };
    
    #endif /* SPORTBAG_HPP_ */

    OutdoorBag.hpp:

    #ifndef OUTDOORBAG_HPP_
    #define OUTDOORBAG_HPP_
    
    #include <iostream>
    #include "Bag.hpp"
    
    class COutdoorBag : public CBag
    {
    public:
        COutdoorBag(){}
        virtual ~COutdoorBag(){}
    
        virtual void Operation()
        {
            cout << "Outdoor bag ";
        }
    };
    
    #endif /* OUTDOORBAG_HPP_ */

    DecoratorBag.hpp:

    #ifndef DECORATORBAG_HPP_
    #define DECORATORBAG_HPP_
    
    #include "Bag.hpp"
    
    class CDecoratorBag : public CBag
    {
    public:
        CDecoratorBag(CBag* pBag)
        {
            m_pBag = pBag;
        }
    
        virtual ~CDecoratorBag(){}
    
        virtual void Operation()
        {
            m_pBag->Operation();
        }
    
    private:
        CBag* m_pBag;
    };
    
    #endif /* DECORATORBAG_HPP_ */

    QmmDecoratorBag.hpp:

    #ifndef QMMDECORATORBAG_HPP_
    #define QMMDECORATORBAG_HPP_
    
    #include <iostream>
    #include "DecoratorBag.hpp"
    
    class CQmmDecoratorBag : public CDecoratorBag
    {
    public:
        CQmmDecoratorBag(CBag* pBag) : CDecoratorBag(pBag)
        {
        }
    
        virtual ~CQmmDecoratorBag(){}
    
        virtual void Operation()
        {
            CDecoratorBag::Operation();
            Hang();
        }
    
    protected:
        void Hang()
        {
            cout << "with accouterment QMM." << endl;
        }
    };
    
    #endif /* QMMDECORATORBAG_HPP_ */

    QggDecoratorBag.hpp:

    #ifndef QGGDECORATORBAG_HPP_
    #define QGGDECORATORBAG_HPP_
    
    #include <iostream>
    #include "DecoratorBag.hpp"
    
    class CQggDecoratorBag : public CDecoratorBag
    {
    public:
        CQggDecoratorBag(CBag* pBag) : CDecoratorBag(pBag)
        {
        }
    
        virtual ~CQggDecoratorBag(){}
    
        virtual void Operation()
        {
            CDecoratorBag::Operation();
            Hang();
        }
    
    protected:
        void Hang()
        {
            cout << "with accouterment QGG." << endl;
        }
    };
    
    #endif /* QGGDECORATORBAG_HPP_ */

    DecoratorMain.cpp:

    #include <iostream>
    #include "Bag.hpp"
    #include "SportBag.hpp"
    #include "OutdoorBag.hpp"
    #include "DecoratorBag.hpp"
    #include "QggDecoratorBag.hpp"
    #include "QmmDecoratorBag.hpp"
    
    using namespace std;
    
    int main()
    {
        CBag* bag;
        CBag* sportBag = new CSportBag();
        CBag* outdoorBag = new COutdoorBag();
        bag = new CQggDecoratorBag(sportBag);
    
        bag->Operation();
    
        delete bag;
        delete sportBag;
        delete outdoorBag;
    
        return 0;
    }

    https://github.com/Bwar/Nebula

  • 相关阅读:
    iOS学习之自定义UItableViewCell
    iOS学习之UItableView
    iOS学习之懒加载
    iOS学习之根据文本内容动态计算文本框高度的步骤
    iOS学习之导航条NavigationControl的一些属性设置
    iOS: TableView如何刷新指定的cell 或section
    时间戳比较
    UIScrollView 去掉下面的滚动条
    iOS中navigationItem修改标题的颜色
    swift 下storyboard的页面跳转和传值
  • 原文地址:https://www.cnblogs.com/bwar/p/9190948.html
Copyright © 2011-2022 走看看