设计模式 - 模板方法模式(Template Method Pattern)

设计模式 - 模板方法模式(Template Method Pattern)

flyfish

模板方法模式(Template Method Pattern)是一种行为型设计模式,它定义了一个算法的骨架,而将某些步骤的实现延迟到子类中。通过这种方式,模板方法模式允许子类在不改变算法结构的情况下,重新定义算法中的某些步骤。

C++ 里面也有模板, C++ 模板(Templates)是一种编程语言特性,主要用于实现通用编程,允许在编译时生成适用于不同数据类型的代码。这里的模板方法模式是一个设计模式,强调的是定义算法的骨架,允许子类改变算法的某些步骤。

模板方法模式的核心思想

  1. 算法骨架 :在一个抽象类中定义一个算法的骨架。这个骨架是一个具体的方法,称为模板方法。

  2. 步骤实现 :算法的某些步骤由抽象方法定义,这些方法需要在子类中实现。

  3. 不变的部分和可变的部分 :模板方法模式将算法中不变的部分放在抽象类中,而将可变的部分留给子类实现。

模板方法模式的结构

  • AbstractClass(抽象类)
    包含一个或多个模板方法,定义了算法的骨架。
    包含一些基本方法,其中可以有抽象方法和钩子方法。

  • ConcreteClass(具体类)
    继承自 AbstractClass,实现抽象类中的抽象方法,定义具体步骤。

简单示例,展示制作饮料的过程

#include <iostream>

// 抽象类,定义饮料制作的模板方法
class Beverage {
public:
    // 模板方法,定义制作饮料的步骤
    void prepareBeverage() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }

    // 基本方法:煮沸水
    void boilWater() {
        std::cout << "Boiling water" << std::endl;
    }

    // 基本方法:倒入杯中
    void pourInCup() {
        std::cout << "Pouring into cup" << std::endl;
    }

    // 抽象方法:冲泡饮料(由子类实现)
    virtual void brew() = 0;

    // 抽象方法:添加调料(由子类实现)
    virtual void addCondiments() = 0;
};

// 具体类:咖啡
class Coffee : public Beverage {
protected:
    void brew() override {
        std::cout << "Brewing coffee" << std::endl;
    }

    void addCondiments() override {
        std::cout << "Adding sugar and milk" << std::endl;
    }
};

// 具体类:茶
class Tea : public Beverage {
protected:
    void brew() override {
        std::cout << "Steeping tea" << std::endl;
    }

    void addCondiments() override {
        std::cout << "Adding lemon" << std::endl;
    }
};

int main() {
    Coffee coffee;
    Tea tea;

    std::cout << "Preparing coffee:" << std::endl;
    coffee.prepareBeverage();

    std::cout << "\nPreparing tea:" << std::endl;
    tea.prepareBeverage();

    return 0;
}

代码示例 定义一个抽象基类 GameAI 来定义算法的骨架,并由具体子类如 OrcsAIMonstersAI 实现具体的步骤使用 C++ 的抽象类和继承来实现这一模式

  1. 抽象基类 GameAI
    包含一个模板方法 turn(),定义了算法的框架。
    提供一个具体实现的方法 collectResources()
    定义了一些纯虚函数(抽象方法),如 buildStructures()buildUnits()sendScouts()sendWarriors(),由子类实现。

  2. 具体类 OrcsAIMonstersAI
    继承自 GameAI,并实现了所有抽象方法。
    OrcsAI 实现了具体的建造和攻击策略。
    MonstersAI 覆盖了 collectResources() 方法,并实现了它们自己的攻击逻辑。

#include <iostream>
#include <vector>
#include <string>

// 抽象基类:GameAI
class GameAI {
public:
    // 模板方法定义算法的框架
    void turn() {
        collectResources();
        buildStructures();
        buildUnits();
        attack();
    }

    // 某些步骤可以在基类中实现
    virtual void collectResources() {
        for (auto& structure : builtStructures) {
            structure.collect();
        }
    }

    // 抽象方法,由子类实现
    virtual void buildStructures() = 0;
    virtual void buildUnits() = 0;

    // 一个类可以包含多个模板方法
    void attack() {
        auto enemy = closestEnemy();
        if (enemy.empty()) {
            sendScouts("map center");
        } else {
            sendWarriors(enemy);
        }
    }

    // 抽象方法,由子类实现
    virtual void sendScouts(const std::string& position) = 0;
    virtual void sendWarriors(const std::string& position) = 0;

protected:
    // 模拟已建造结构的集合
    struct Structure {
        void collect() {
            std::cout << "Collecting resources from structure.\n";
        }
    };
    std::vector<Structure> builtStructures;

    // 模拟查找最近的敌人
    std::string closestEnemy() {
        return "enemy position";
    }
};

// 具体类:OrcsAI
class OrcsAI : public GameAI {
public:
    void buildStructures() override {
        std::cout << "Orcs are building structures.\n";
    }

    void buildUnits() override {
        std::cout << "Orcs are building units.\n";
    }

    void sendScouts(const std::string& position) override {
        std::cout << "Orcs sending scouts to " << position << ".\n";
    }

    void sendWarriors(const std::string& position) override {
        std::cout << "Orcs sending warriors to " << position << ".\n";
    }
};

// 具体类:MonstersAI
class MonstersAI : public GameAI {
public:
    void collectResources() override {
        std::cout << "Monsters do not collect resources.\n";
    }

    void buildStructures() override {
        std::cout << "Monsters do not build structures.\n";
    }

    void buildUnits() override {
        std::cout << "Monsters do not build units.\n";
    }

    void sendScouts(const std::string& position) override {
        std::cout << "Monsters sending scouts to " << position << ".\n";
    }

    void sendWarriors(const std::string& position) override {
        std::cout << "Monsters sending warriors to " << position << ".\n";
    }
};

int main() {
    OrcsAI orcsAI;
    MonstersAI monstersAI;

    std::cout << "Orcs AI turn:\n";
    orcsAI.turn();

    std::cout << "\nMonsters AI turn:\n";
    monstersAI.turn();

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西笑生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值