• c++设计模式:模板方法模式(Template Method Pattern)


    定义:模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

    钩子的定义:钩子是一种被声明在抽象类中的方法,但只有空的或者默认的实现。钩子的存在,可以让子类有能力对算法的不同点进行挂钩。究竟需不需要挂钩,则由子类自行决定。

    场景:我们有一个咖啡厅,有一个专门的配方来调制咖啡喝茶,在调制的过程中的某些方法其实是比较类似的,步骤如下:

    1、把水煮沸

    2、用热水泡咖啡或茶

    3、把饮料倒进杯子

    4、在饮料内加入适当的调料,咖啡要加糖和牛奶,而茶需要加柠檬。在调料添加的时候,我们需要询问顾客是否需要添加调料,此时就会用到钩子。

    类图:

    c++代码如下:

    #include <iostream>
    using namespace std;

    class CaffeineBeverage
    {
    public:
    void prepareRecipe();
    private:
    virtual void brew() = 0;
    virtual void addCondiments() = 0;
    void boilWater();
    void pourInCup();
    virtual bool customerWantsCondiments(); // 钩子
    };

    class Coffee : public CaffeineBeverage
    {
    private:
    void brew();
    void addCondiments();
    bool customerWantsCondiments();
    };

    class Tea : public CaffeineBeverage
    {
    private:
    void brew();
    void addCondiments();
    bool customerWantsCondiments();
    };

    void CaffeineBeverage::prepareRecipe()
    {
    boilWater();
    brew();
    pourInCup();
    if (customerWantsCondiments())
    {
    addCondiments();
    }
    }

    void CaffeineBeverage::boilWater()
    {
    printf("把水煮沸\n");
    }

    void CaffeineBeverage::pourInCup()
    {
    printf("倒入杯子中\n");
    }

    bool CaffeineBeverage::customerWantsCondiments()
    {
    return true;
    }

    void Coffee::brew()
    {
    printf("用沸水冲泡咖啡粉\n");
    }

    void Coffee::addCondiments()
    {
    printf("加糖和牛奶\n");
    }

    bool Coffee::customerWantsCondiments()
    {
    char zAnswer;
    printf("您的咖啡中是否需要牛奶和糖:");
    fflush(stdin);
    zAnswer = getchar();
    zAnswer = toupper(zAnswer);
    if ('Y'==zAnswer)
    {
    return true;
    }
    else if ('N'==zAnswer)
    {
    return false;
    }
    else
    {
    printf("输入错误,默认不加调料\n");
    return false;
    }
    }

    void Tea::brew()
    {
    printf("用沸水浸泡茶叶\n");
    }
    void Tea::addCondiments()
    {
    printf("加柠檬\n");
    }

    bool Tea::customerWantsCondiments()
    {
    char zAnswer;
    printf("您的茶中是否需要柠檬:");
    fflush(stdin);
    zAnswer = getchar();
    zAnswer = toupper(zAnswer);
    if ('Y'==zAnswer)
    {
    return true;
    }
    else if ('N'==zAnswer)
    {
    return false;
    }
    else
    {
    printf("输入错误,默认不加调料\n");
    return false;
    }
    }

    int main()
    {
    Coffee coffee;
    Tea tea;
    coffee.prepareRecipe();
    tea.prepareRecipe();
    return 0;
    }

    运行结果:

    把水煮沸
    用沸水冲泡咖啡粉
    倒入杯子中
    您的咖啡中是否需要牛奶和糖:y
    加糖和牛奶
    把水煮沸
    用沸水浸泡茶叶
    倒入杯子中
    您的茶中是否需要柠檬:n

    解说:模板方法模式是一个很常见的模式,到处都是。在实际应用中,模板方法有许多的实现,而它们看起来并不一定和书上所讲的设计一致。这个设计常见,是因为对创建框架来说,这个模式简直棒极了,由框架控制如何做事情,而由使用框架的人来指定框架算法中的每个步骤的细节。

    参考图书:《Head First 设计模式》

  • 相关阅读:
    NodeJS加MongoDB应用入门
    调试NodeJS应用
    二月一号博客
    大三寒假第二篇学习记录
    大三寒假第一篇学习记录
    jQuery处理json数据
    Mapreduce案例测试
    你的灯还亮着吗?发现问题的真正所在(一)
    大型数据库技术(一)
    暑假第八周博客
  • 原文地址:https://www.cnblogs.com/osyun/p/2343999.html
Copyright © 2020-2023  润新知