
策略模式和模板模式是行为型设计模式中非常经典的两种模式核心区别在于封装的变化点和控制流方向完全不同以下是详细对比一、核心定义与核心思想策略模式封装一系列可互相替换的算法/行为让算法的变化独立于使用它的客户端核心是算法平等、横向替换。模板模式定义一个操作的算法骨架将部分步骤延迟到子类实现核心是骨架固定、步骤纵向扩展。二、核心维度详细对比控制流方向策略模式所有策略是平级的客户端主动选择并注入具体策略执行逻辑完全由策略自身决定没有固定的执行顺序约束。模板模式父类定义好固定的执行流程骨架子类只能填充指定的抽象步骤不能改变整体执行顺序父类掌控流程控制权。代码复用逻辑策略模式复用的是完整的独立算法不同策略之间几乎没有公共逻辑仅对外暴露统一的执行接口。模板模式复用的是公共的流程骨架子类只需要实现差异化的步骤大量公共逻辑都放在父类中统一实现。继承/组合的使用策略模式以组合为核心实现方式上下文类持有策略接口的引用通过组合不同的策略对象切换行为符合“组合优于继承”原则。模板模式以继承为核心实现方式子类继承抽象模板类重写其中的抽象方法来完成步骤扩展。新增实现的成本策略模式新增策略只需要实现策略接口完全不修改原有代码符合开闭原则扩展非常灵活。模板模式新增步骤实现需要继承抽象模板类如果要修改流程骨架必须修改父类代码扩展灵活性弱于策略模式。典型适用场景策略模式适用于多种算法需要动态切换的场景比如支付方式选择微信/支付宝/银行卡、排序算法切换、不同促销活动的计价逻辑。模板模式适用于流程固定、部分步骤差异化的场景比如Spring中Bean的生命周期流程、文件解析不同格式文件解析步骤不同但整体流程一致、考试答题流程发卷-答题-交卷固定不同科目答题逻辑不同。三、核心区别汇总表对比维度策略模式模板模式核心思想算法平等替换流程骨架固定步骤延迟实现核心实现方式组合继承流程控制权客户端/上下文持有抽象父类持有扩展灵活性极高新增策略无需改原有代码较低改骨架需修改父类典型场景动态切换算法/行为固定流程下的步骤差异化实现四Java完整可运行对比代码importjava.util.Scanner;// 1. 策略模式 (Strategy Pattern) // 策略接口interfacePaymentStrategy{voidpay(doubleamount);}// 具体策略微信支付classWeChatPayimplementsPaymentStrategy{Overridepublicvoidpay(doubleamount){System.out.println([策略-微信] 正在调用微信接口支付: amount元);}}// 具体策略支付宝支付classAliPayimplementsPaymentStrategy{Overridepublicvoidpay(doubleamount){System.out.println([策略-支付宝] 正在调用支付宝接口支付: amount元);}}// 上下文持有策略引用classOrderContext{privatePaymentStrategystrategy;publicOrderContext(PaymentStrategystrategy){this.strategystrategy;}// 动态切换策略publicvoidsetStrategy(PaymentStrategystrategy){this.strategystrategy;}publicvoidcheckout(doubleamount){if(strategynull){thrownewIllegalStateException(未选择支付方式);}strategy.pay(amount);}}// 2. 模板模式 (Template Pattern) // 抽象模板类abstractclassAbstractExam{// 模板方法定义固定流程final防止子类篡改顺序publicfinalvoidtakeExam(){distributePaper();// 公共步骤1answerQuestions();// 差异步骤由子类实现submitPaper();// 公共步骤2}privatevoiddistributePaper(){System.out.println([模板-考试] 监考老师统一发放试卷...);}// 抽象方法子类必须实现的具体业务逻辑protectedabstractvoidanswerQuestions();privatevoidsubmitPaper(){System.out.println([模板-考试] 考生统一提交试卷...);}}// 具体实现数学考试classMathExamextendsAbstractExam{OverrideprotectedvoidanswerQuestions(){System.out.println([模板-数学] 正在计算几何与代数题目...);}}// 具体实现英语考试classEnglishExamextendsAbstractExam{OverrideprotectedvoidanswerQuestions(){System.out.println([模板-英语] 正在进行听力播放与阅读理解...);}}// 3. 主程序入口 publicclassPatternDemo{publicstaticvoidmain(String[]args){System.out.println( 演示 1: 策略模式 (动态切换算法) );// 1. 创建上下文OrderContextordernewOrderContext(newWeChatPay());// 2. 执行支付order.checkout(100.0);// 3. 运行时动态切换策略order.setStrategy(newAliPay());order.checkout(200.0);System.out.println(\n 演示 2: 模板模式 (固定流程骨架) );// 1. 创建不同科目的考试对象AbstractExammathExamnewMathExam();AbstractExamenglishExamnewEnglishExam();// 2. 执行固定流程但内部答题逻辑不同System.out.println(-- 开始数学考试 --);mathExam.takeExam();System.out.println(-- 开始英语考试 --);englishExam.takeExam();}}五、 运行结果预期六、 核心差异代码级解读扩展方式策略模式新增支付方式只需新建类实现 PaymentStrategy 接口OrderContext 无需修改。模板模式新增考试科目需新建类继承 AbstractExam 并重写 answerQuestions若需增加“收卷”步骤则需修改父类。耦合度策略模式低耦合通过接口交互符合依赖倒置原则。模板模式高耦合子类强依赖父类的流程控制符合里氏替换原则。七总结如果你的需求是多个平级的算法可以互相替换优先选择策略模式如果你的需求是一套固定的执行流程只有个别步骤需要自定义优先选择模板模式。