C++模板方法模式


模板方法模式是一种行为设计模式,它定义了一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变算法的结构即可重定义该算法的某些特定步骤。这种模式非常适合需要控制算法流程,同时允许子类自定义部分行为的场景。

在C++中实现模板方法模式的基本步骤如下:

1. 定义抽象基类(Abstract Class)

首先,定义一个抽象基类,这个基类中包含了一个或多个模板方法和一些抽象方法或具体方法。模板方法定义了算法的整体框架,而抽象方法则是留给子类实现的。

class AbstractClass {
public:
    // 模板方法,定义了算法的骨架
    void templateMethod() {
        primitiveOperation1();
        primitiveOperation2();
    }

    // 抽象方法,由子类实现
    virtual void primitiveOperation1() = 0;
    
    // 可能还有其他抽象或具体方法
    virtual void primitiveOperation2() {
        // 默认实现
    }
protected:
    // 可能包含受保护的辅助方法
};

2. 实现具体子类(Concrete Class)

然后,创建抽象基类的子类,并实现其中的抽象方法。子类可以根据需要重写具体方法,但模板方法的结构保持不变。

class ConcreteClassA : public AbstractClass {
public:
    void primitiveOperation1() override {
        // 实现具体操作1
    }
    
    // 如果需要,也可以重写primitiveOperation2
};

class ConcreteClassB : public AbstractClass {
public:
    void primitiveOperation1() override {
        // 实现与ConcreteClassA不同的操作1
    }
};

3. 使用模板方法

客户端代码仅需调用模板方法,而无需知道算法的具体实现细节,提高了代码的抽象层次和复用性。

int main() {
    AbstractClass* a = new ConcreteClassA();
    a->templateMethod();
    delete a;

    AbstractClass* b = new ConcreteClassB();
    b->templateMethod();
    delete b;

    return 0;
}

在这个例子中,templateMethod是模板方法,它定义了执行操作的顺序,而primitiveOperation1primitiveOperation2是抽象方法,由子类实现具体的业务逻辑。这样,我们可以在不修改模板方法的情况下,通过更换不同的子类来改变算法的部分步骤,实现了算法的结构稳定性和步骤可变性的良好平衡。

模板方法模式的优点

  1. 代码复用:模板方法模式在一个类中定义了算法的骨架,而将一些步骤延迟到子类中实现,这使得相同的基本算法可以有不同的具体实现,提高了代码的复用性。

  2. 封装不变部分:将算法中的不变部分(算法的框架)封装在基类的模板方法中,确保了算法整体结构的稳定性和一致性。

  3. 扩展性好:新增新的具体实现时,只需要添加新的子类并实现相应的抽象方法,而不需要修改现有的类库代码,符合开闭原则。

  4. 行为控制:父类可以通过控制模板方法中的逻辑顺序,来控制子类的行为,增强了对系统行为的集中控制。

模板方法模式的应用场景

  • 框架开发:许多软件框架会使用模板方法模式定义其核心流程,而将具体实现留给用户自定义。比如,Junit测试框架中的测试用例运行流程就是一个模板方法模式的例子。

  • UI框架:在图形用户界面(GUI)框架中,绘制组件或处理事件的流程往往是一个固定的模板,而具体的绘制内容或事件响应则由各个组件自己实现。

  • 数据库访问库:数据库操作通常包括打开连接、执行查询、处理结果集、关闭连接等固定步骤,这些步骤可以作为模板方法定义,而具体的SQL语句和结果处理由子类实现。

注意事项

  • 避免过度设计:虽然模板方法模式可以增加代码的灵活性和扩展性,但如果滥用可能导致系统结构过于复杂,增加了理解和维护的难度。

  • 性能考量:由于涉及到虚函数调用,模板方法模式在性能敏感的应用中可能需要权衡。虽然现代编译器的优化已经大大减少了这种开销,但在极端性能要求下仍需注意。

  • 设计决策:确定哪些部分作为模板方法,哪些部分留给子类实现,需要仔细考虑,以达到既灵活又不失控制的目的。

总之,模板方法模式是面向对象设计中一种非常实用的模式,适用于需要定义算法框架并允许子类对部分步骤进行定制化的场景。正确使用它可以显著提升代码的结构和可维护性。

实现示例

为了更好地理解模板方法模式,下面通过一个简单的例子来说明其应用:假设我们正在设计一个冲泡饮料的框架,无论是咖啡还是茶,冲泡过程都包含几个通用步骤(烧水、加入原料、搅拌、倒入杯中),但具体每个步骤的实现细节(如原料种类)根据不同饮料而异。

抽象类(模板)

首先,我们定义一个抽象类Beverage,它充当模板方法模式中的抽象模板角色,定义了冲泡饮料的整个流程框架。

public abstract class Beverage {
    // 模板方法,定义冲泡流程
    public final void brew() {
        boilWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) {
            addCondiments();
        }
    }

    // 基本方法,由子类实现
    protected abstract void brew(); // 冲泡(咖啡或茶)
    protected abstract void addCondiments(); // 添加调料(奶、糖等)

    // 具体方法,已实现
    private void boilWater() {
        System.out.println("Boiling water");
    }

    private void pourInCup() {
        System.out.println("Pouring into cup");
    }

    // 钩子方法,可被子类重写以改变默认行为
    protected boolean customerWantsCondiments() {
        return true;
    }
}
具体实现类

然后,我们创建两个具体实现类,分别代表咖啡(Coffee)和茶(Tea),它们继承自Beverage类,并实现其中的抽象方法。

public class Coffee extends Beverage {
    @Override
    protected void brew() {
        System.out.println("Brewing Coffee");
    }

    @Override
    protected void addCondiments() {
        System.out.println("Adding Sugar and Milk to Coffee");
    }
}

public class Tea extends Beverage {
    @Override
    protected void brew() {
        System.out.println("Steeping the Tea");
    }

    @Override
    protected void addCondiments() {
        System.out.println("Adding Lemon");
    }
}
客户端代码

最后,客户端代码仅需实例化具体饮料类并调用brew()方法,无需关注冲泡的具体步骤。

public class StarbuzzCoffee {
    public static void main(String[] args) {
        Beverage beverage = new Coffee();
        beverage.brew();

        System.out.println("\n");

        beverage = new Tea();
        beverage.brew();
    }
}

总结

通过这个例子,我们可以看到模板方法模式如何将算法的骨架与具体实现细节分离开来,使得算法的整体结构保持不变的同时,允许子类对某些步骤进行定制,从而提高了代码的复用性和灵活性。

😍😍 大量H5小游戏、微信小游戏、抖音小游戏源码😍😍
😍😍试玩地址: https://www.bojiogame.sg😍😍
😍看上哪一款,需要源码的csdn私信我😍

————————————————

​最后我们放松一下眼睛
在这里插入图片描述

  • 34
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
模板方法设计模式是一种行为设计模式,它定义了一个算法的骨架,将一些步骤的实现延迟到子类中。这种模式可以确保算法的结构保持不变,但允许子类提供特定的实现细节。在C++中,模板方法设计模式可以通过使用虚函数和继承来实现。 在给出的引用中,我们可以看到一个名为CoffeineBeverage的类,它定义了一个prepare_recipe()方法,并在内部调用了其他几个私有方法。这个类是一个基类,可以被子类继承并重写其中的方法。 具体来说,模板方法设计模式的关键是将算法的骨架定义在基类中,而将可变的实现细节留给子类去实现。在这个例子中,prepare_recipe()方法是算法的骨架,而brew()和add_condiments()方法则是可变的实现细节。 通过将brew()和add_condiments()方法定义为虚函数,基类CoffeineBeverage允许子类去重写这些方法以提供自己的实现。这样,当调用prepare_recipe()方法时,实际执行的是子类中重写后的方法。 使用模板方法设计模式的好处是可以提高代码的复用性和可扩展性。算法的骨架在基类中只需要定义一次,而具体的实现细节可以在不同的子类中灵活变化。 总结起来,C++中的模板方法设计模式通过定义一个算法的骨架并将可变的实现细节留给子类去实现,可以提供代码的复用性和可扩展性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [C++设计模式模板方法模式](https://blog.csdn.net/Long_xu/article/details/127118813)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [C++设计模式-模板方法模式](https://blog.csdn.net/qq78442761/article/details/91990149)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

极致人生-010

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

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

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

打赏作者

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

抵扣说明:

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

余额充值