• 组件协作模式


    组件协作模式概念

    • 现代软件专业分工之后的第一个结果是“框袈与应用程序的划分”,“组件协作”模式通过晚期绑定,来实现框架与应用程序之间的松耦合,是二者之间协作时常用的模式。

    1、模板方法模式(Template_Method)

    动机(Motivation)

    • 在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现。
    • 如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变化或者晚期实现需求?

    模式定义

    • 定义一个操作中的算法的骨架(稳定),而将一些步骤延迟(变化)到子类中。Template Mthod 使得子类可以不改变(复用)一个算法的结构即可重定义(override 重写)该算法某些特定步骤。

    先给出一个类的设计图
    在这里插入图片描述

    具体代码举例实现

    1. 先给出未使用模板方法的设计,把主要的主流程设计丢给了主程序,交给后面的人设计
    #include 
    
    using namespace std;
    
    class Library
    {
    public:
        void step1()
        {
            cout << "step1()" << endl;
        }
    
        void step3()
        {
            cout << "step3()" << endl;
        }
    
        void step5()
        {
            cout << "step5()" << endl;
        }
    };
    
    class Application
    {
    public:
        bool step2()
        {
            cout << "step2()" << endl;
            return true;
        }
    
        bool step4()
        {
            cout << "step4()" << endl;
            return true;
        }
    };
    
    int main()
    {
        Library lib;
        Application app;
        lib.step1();
    
        if (app.step2())
        {
            lib.step3();
        }
    
        if (app.step4())
        {
            lib.step5();
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    1. 给出使用模板方法模式的设计,主流程框架稳定不动,由Libray类设计
    #include 
    
    using namespace std;
    
    class Library
    {
    public:
        virtual ~Library() {};
    
    public:
        // 主流程
        void run()
        {
            step1();
    
            if (step2())
            {
                step1();
            }
            if (step4())
            {
                step5();
            }
        }
    
    
        void step1()
        {
            cout << "step1()" << endl;
        }
    
        void step3()
        {
            cout << "step3()" << endl;
        }
    
        void step5()
        {
            cout << "step5()" << endl;
        }
    
    
    protected:
        virtual bool step2() = 0;
        virtual bool step4() = 0;
    };
    
    class Application : public Library
    {
    public:
        bool step2()
        {
            cout << "step2()" << endl;
            return true;
        }
    
        bool step4()
        {
            cout << "step4()" << endl;
            return true;
        }
    };
    
    int main()
    {
        Library* lib = new Application;
        lib->run();
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    要点总结

    • Template Method 模式是一种非常基础性的设计模式,在面向对象系统中有着大量的应用。它用最简洁的机制(虚函数的多态性)为很多应用程序框架提供了灵活的扩展点,是代码复用方面的基本实现结构。
    • 除了可以灵活应对子步骤的变化外,“不要调用我,让我来调用你”的反向控制结构是Template Method的典型应用。
    • 在具体实现方面,被Template Method调用的虚方法可以具有实现,也可以没有任何实现(抽象方法、纯虚方法),但一般推荐将它们设置为protected方法。

    2、策略模式(Strategy)

    动机(Motivation)

    • 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂;而且有时候支持不使用的算法也是一个性能负担。
    • 如何在运行时根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题?

    模式定义

    • 定义一系列算法,把它们一个个封装起来,并且使它们可互相替换(变化)。该模式使得算法可独立于使用它的客户程序(稳定)而变化(扩展,子类化)。

    具体代码举例实现

    1. 未使用策略模式之前,这里的需要更改的时候违背了开闭原则
    enum TaxBase
    {
        CN_Tax,
        US_Tax,
        DE_Tax
        // FD_Tax   增加新功能时
    };
    
    class SalesOrder
    {
        TaxBase tax;
    public:
        double Calculate()
        {
    
            if (tax == CN_Tax) {
    
            }
            else if (tax == US_Tax) {
    
            }
            else if (tax == DE_Tax) {
    
            }
            //else if (tax == FD_Tax) {}    增加新功能时
    
    
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    1. 使用策略模式,这里的更改只需要增加新的类,也就是扩展,并且自己实现自己的算法细节
    class TaxStrategy
    {
    public:
        virtual ~TaxStrategy() {}
    protected:
        virtual double Calculate() = 0;
    };
    
    
    class CNTax : public TaxStrategy
    {
    public:
        double Calculate() {}
    };
    
    class USTax : public TaxStrategy
    {
    public:
        double Calculate() {}
    };
    
    // 增加功能时
    // class FDTax : public TaxStrategy
    // {
    // public:
    //     double Caculate() {}
    // };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    要点总结

    • Strategy及其子类为组件提供了一系列可重用的算法,从而可以使得类型在运行时方便地根据需要在各个算法之间进行切换。
    • Strategy模式提供了用条件判断语句以外的另一种选择,消除条件判断语苟,就是在解耦合。含有许多条件判断语句的代码涌堂都需要Strategy模式。
    • 如果Strategy对象没有实例变量,那么各个上下文可以共享同一个Strategy对象,从而节省对象开销。

    3、观察者模式(Observer/Event)

    动机(Motivation )

    • 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系——一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,将使软件不能很好地抵御变化。
    • 使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合

    模式定义

    • 定义对象间的一种**一对多(变化)**的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。

    代码具体实现

    1. 当一个改变了通知多个观察者
    #include 
    #include 
    
    using namespace std;
    
    // 先声明观察者,observer是观察者
    class Observer
    {
    public:
        virtual void doObserver() = 0;
        virtual ~Observer() {}
    };
    
    // 通知者,这个类可以一直不动,无论有多少个新的消息
    class Observerable
    {
        typedef list<Observer*>::iterator listIterator;
        list<Observer*> observerList;
    public:
        // 有消息通知过来了
        void addObserver(Observer* observer) {
            observerList.push_back(observer);
        }
        // 删除消息的通知
        void removeObserver(Observer* observer) {
            observerList.remove(observer);
        }
    
        void notify() {
            // 对所有的消息进行处理
            listIterator itor = observerList.begin();
            while (itor != observerList.end()) {
                (*itor)->doObserver();
                itor = observerList.erase(itor);
            }
        }
    };
    
    class Observer_one : public Observer
    {
    public:
        virtual void doObserver() {
            cout << "." << endl;
        }
    };
    
    class Observer_two : public Observer
    {
    public:
        virtual void doObserver() {
            cout << "-" << endl;
        }
    };
    
    
    int main()
    {
        Observerable ob;
        // 比如我现在改变了某一个值,通知几个观察者
        ob.addObserver(new Observer_one);
        ob.addObserver(new Observer_two);
        ob.notify();
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    要点总结

    • 使用面向对象的抽象,Observer模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达致松耦合。
    • 目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播。
    • 观察者自己决定是否需要订阅通知,目标对象对此一无所知。
    • Observer模式是基于事件的UI框架中非常常用的设计模式,也是MVC模式的一个重要组成部分。
  • 相关阅读:
    Navicat 16 支持 Redis Cluster 集群模式 | 新功能 √
    JAVA计算机毕业设计小型企业员工工资管理系统(附源码、数据库)
    praat 脚本出错(提取textgrid中所标注的特定部分并存入新建文件夹,最后删除空的新建文件夹)
    【图像分类】【深度学习】【轻量级网络】【Pytorch版本】MobileNets_V2模型算法详解
    【Linux】shell命令以及运行原理和Linux权限详解
    threejs开发太阳系案例
    人工智能驱动的自然语言处理:解锁文本数据的价值
    midway的使用教程
    四.Docker容器技术
    2023年09月 C/C++(三级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • 原文地址:https://blog.csdn.net/z2812470857/article/details/133834635