zoukankan      html  css  js  c++  java
  • C++ 设计模式 开放封闭原则 简单示例

    C++ 设计模式 开放封闭原则 简单示例

    开放封闭原则(Open Closed Principle)描述

    符合开放封闭原则的模块都有两个主要特性:

    1. 它们 "面向扩展开放(Open For Extension)"。

    也就是说模块的行为是能够被扩展的。当应用程序的需求变化时,我们可以使模块表现出全新的或与以往不同的行为,以满足新的需求。

    2. 它们 "面向修改封闭(Closed For Modification)"。

    模块的源代码是不能被侵犯的,任何人都不允许修改已有源代码。

    类关系示意图: 

    /*
     * 开放封闭原则(OCP, Open For Extension, Closed For Modification Principle)
     * 软件实体(类、模块、函数等)应对扩展开放,但对修改封闭。
     * 
     */
    
    #include <iostream>
    
    class Banker
    {
    public:
        // 抽象类的构造函数不能是虚函数, 因为虚函数的实现依赖于虚函数表, 在对象没有构造好之前, 对象自己所要占用的空间还是一片混沌, 自己的虚函数表是没法用的
        // 在构造函数中调用虚函数, 实际执行的是父类的对应函数, 因为自己还没有构造好, 多态是被关闭的
        Banker()
        {
            std::cout << "构造 Banker" << std::endl;
        }
        // 抽象类的析构函数通常为虚函数, 否则可能导致资源泄漏, 非纯虚函数必须有定义体, 否则编译错误
        // 析构函数可以是纯虚函数, 但纯虚析构函数必须有定义体, 因为析构函数的调用是在子类中隐含的
        virtual ~Banker()
        {
            std::cout << "析构 Banker" << std::endl;
        }
        // 包含纯虚函数的类, 是一个抽象类, 将不能实例化对象
        // 虚函数是动态绑定的, 也就是说, 使用虚函数的指针和引用能够正确找到实际类的对应函数, 而不是执行定义类的函数
        // 在C++中,只要原来的返回类型是指向类的指针或引用,新的返回类型是指向派生类的指针或引用,覆盖的方法就可以改变返回类型。这样的类型称为协变返回类型(Covariant returns type).
        // 派生类的override虚函数定义必须和父类完全一致, 除了一个特例, 如果父类中返回值是一个指针或引用, 子类override时可以返回这个指针(或引用)的派生
        virtual void doWorks() = 0;
    };
    
    class FunkuanBanker: public Banker
    {
    public:
        FunkuanBanker()
        {
            std::cout << "构造 FunkuanBanker" << std::endl;
        }
        virtual ~FunkuanBanker()
        {
            std::cout << "析构 FunkuanBanker" << std::endl;
        }
        virtual void doWorks() override
        {
            std::cout << "我是银行业务员-负责【付款】业务" << std::endl;
        }
    };
    
    class QukuanBanker: public Banker
    {
    public:
        QukuanBanker()
        {
            std::cout << "构造 QukuanBanker" << std::endl;
        }
        virtual ~QukuanBanker()
        {
            std::cout << "析构 QukuanBanker" << std::endl;
        }
        virtual void doWorks() override
        {
            std::cout << "我是银行业务员-负责【取款】业务" << std::endl;
        }
    };
    
    class ZhuanzhangBanker: public Banker
    {
    public:
        ZhuanzhangBanker()
        {
            std::cout << "构造 ZhuanzhangBanker" << std::endl;
        }
        virtual ~ZhuanzhangBanker()
        {
            std::cout << "析构 ZhuanzhangBanker" << std::endl;
        }
        virtual void doWorks() override
        {
            std::cout << "我是银行业务员-负责【转账】业务" << std::endl;
        }
    };
    
    class PiliangZhuanzhangBanker: public ZhuanzhangBanker
    {
    public:
        PiliangZhuanzhangBanker()
        {
            std::cout << "构造 PiliangZhuanzhangBanker" << std::endl;
        }
        virtual ~PiliangZhuanzhangBanker()
        {
            std::cout << "析构 PiliangZhuanzhangBanker" << std::endl;
        }
        virtual void doWorks() override
        {
            std::cout << "我是银行业务员-负责【批量转账】业务" << std::endl;
        }
    };
    
    class ZidongPiliangZhuanzhangBanker: public PiliangZhuanzhangBanker
    {
    public:
        ZidongPiliangZhuanzhangBanker()
        {
            std::cout << "构造 ZidongPiliangZhuanzhangBanker" << std::endl;
        }
        virtual ~ZidongPiliangZhuanzhangBanker()
        {
            std::cout << "析构 ZidongPiliangZhuanzhangBanker" << std::endl;
        }
        virtual void doWorks() override
        {
            std::cout << "我是银行业务员-负责【自动批量转账】业务" << std::endl;
        }
    };
    
    class JijingBanker: public Banker
    {
    public:
        JijingBanker()
        {
            std::cout << "构造 JijingBanker" << std::endl;
        }
        virtual ~JijingBanker()
        {
            std::cout << "析构 JijingBanker" << std::endl;
        }
        virtual void doWorks() override
        {
            std::cout << "我是银行业务员-负责【基金】业务" << std::endl;
        }
    };
    
    class OtherBanker: public Banker
    {
    public:
        OtherBanker()
        {
            std::cout << "构造 OtherBanker" << std::endl;
        }
        virtual ~OtherBanker()
        {
            std::cout << "析构 OtherBanker" << std::endl;
        }
        virtual void doWorks() override
        {
            std::cout << "我是银行业务员-负责【其他】业务" << std::endl;
        }
    };
    
    void HowDo(Banker *pbk)
    {
        pbk->doWorks();
    }
    
    void OCP_test()
    {
        Banker *pbk = nullptr;
    
        pbk = new FunkuanBanker;
        HowDo(pbk);
        delete pbk;
        pbk = nullptr;
    
        pbk = new QukuanBanker;
        HowDo(pbk);
        delete pbk;
        pbk = nullptr;
    
        pbk = new ZhuanzhangBanker;
        HowDo(pbk);
        delete pbk;
        pbk = nullptr;
    
        pbk = new PiliangZhuanzhangBanker;
        HowDo(pbk);
        delete pbk;
        pbk = nullptr;
    
        pbk = new ZidongPiliangZhuanzhangBanker;
        HowDo(pbk);
        delete pbk;
        pbk = nullptr;
    
        return;
    }
    
    int main()
    {
        OCP_test();
    
        system("pause");
        return 0;
    }

    运行结果:

  • 相关阅读:
    Python实现天数倒计时计算
    pandas 的数据结构Series与DataFrame
    在python中使用静态方法staticmethod
    python 中对list做减法操作
    推荐系统之 BPR 算法及 Librec的BPR算法实现【1】
    机器学习中的 ground truth
    PyCharm 默认运行 unittest
    Python的copy()与deepcopy()区别
    MySQL中Decimal类型和Float Double的区别 & BigDecimal与Double使用场景
    Spring Boot 返回 JSON 数据,一分钟搞定!
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/7720331.html
Copyright © 2011-2022 走看看