• 设计模式(十)——模板方法模式


    AbstractClass(抽象类):在抽象类中定义了一系列基本操作(PrimitiveOperations),这些基本操作可以是具体的,也可以是抽象的,

    每一个基本操作对应算法的一个步骤,在其子类中可以重定义或实现这些步骤。同时,在抽象类中实现了一个模板方法(Template Method),

    用于定义一个算法的框架,模板方法不仅可以调用在抽象类中实现的基本方法,也可以调用在抽象类的子类中实现的基本方法,还可以调用其他对象中的方法。

    ConcreteClass(具体子类):它是抽象类的子类,用于实现在父类中声明的抽象基本操作以完成子类特定算法的步骤,也可以覆盖在父类中已经实现的具体基本操作

    优点:

    (1) 在父类中形式化地定义一个算法,而由它的子类来实现细节的处理,在子类实现详细的处理算法时并不会改变算法中步骤的执行次序。
    (2) 模板方法模式是一种代码复用技术,它在类库设计中尤为重要,它提取了类库中的公共行为,将公共行为放在父类中,而通过其子类来实现不同的行
     为,它鼓励我们恰当使用继承来实现代码复用。
    (3) 可实现一种反向控制结构,通过子类覆盖父类的钩子方法来决定某一特
    (4) 在模板方法模式中可以通过子类来覆盖父类的基本方法,不同的子类可以提供基本方法的不同实现,更换和增加新的子类很方便,符合单一职责原则
    和开闭原则。

    适用场景
    (1)具有统一的操作步骤或操作过程;
    (2) 具有不同的操作细节;
    (3) 存在多个具有同样操作步骤的应用场景,但某些具体的操作细节却各
    不相同;

    在抽象类中统一操作步骤,并规定好接口;让子类实现接口。这样
    可以把各个具体的子类和操作步骤解耦合。

    #include <iostream>
    
    using namespace std;
    
    class MakeDrink
    {
    public:
        MakeDrink(bool add):m_add(add){}
        // 通用接口
        virtual void boil_water()
        {
            cout << "煮水" << endl;
        }
        // 冲泡,特殊接口
        virtual void brew() = 0;
        // 通用接口
        virtual void pour_in_cup()
        {
            cout << "倒入杯中" << endl;
        }
        // 添加佐料
        virtual void add_condiment() = 0;
    
        // 钩子函数,子类可以通过修改它来控制既有流程得到改变
        virtual bool customer_want_condiment()
        {
            return m_add;
        }
    
        void make()
        {
            boil_water();
            brew();
            pour_in_cup();
            if ( customer_want_condiment() )
                add_condiment();
        }
    protected:
        bool m_add;
    };
    
    class Coffee :public MakeDrink
    {
    public:
        Coffee(bool add):MakeDrink(add)
        {}
    
        virtual void brew()
        {
            cout << "咖啡" << endl;
        }
        virtual void add_condiment()
        {
            cout << "加糖" << endl;
        }
    };
    
    class Tea :public MakeDrink
    {
    public:
        Tea(bool add):MakeDrink(add)
        {}
        virtual void brew()
        {
            cout << "" << endl;
        }
        virtual void add_condiment()
        {
            cout << "柠檬" << endl;
        }
    };
    
    
    int main()
    {
        MakeDrink* coffee = new Coffee(true);
        coffee->make();
    
        cout << "------------------" << endl;
    
        MakeDrink* tea = new Tea(false);
        tea->make();
    
        system("pause");
        return 0;
    }
  • 相关阅读:
    Oracle数据库中truncate命令和delete命令的区别
    数组中只出现一次的数字
    数对之差的最大值
    SQL Server: Difference Between Locking, Blocking and Dead Locking
    字符串处理
    Phpcms_V9任意文件上传
    最初的梦想
    陪你走过漫长岁月
    基于MitM的RDP降级攻击
    CVE-2017-0358
  • 原文地址:https://www.cnblogs.com/xiangtingshen/p/10381079.html
Copyright © 2020-2023  润新知