【设计模式】行为型-模板方法模式
文章目录前言一、概念二、核心结构三、Java 代码实现订单支付流程1. 抽象类定义模板2. 具体子类微信支付3. 具体子类支付宝支付4. 客户端调用四、钩子方法Hook—— 让模板更灵活五、优缺点优点缺点六、应用场景七、模板方法 VS 策略模式八、总结前言在开发中我们经常会遇到业务流程固定、但个别步骤实现不同的场景比如用户注册流程校验、创建、通知、日志、支付流程验签、扣款、回调、日志、数据导入解析、校验、保存、通知。整个流程骨架一样但某几步具体实现不同。如果每个业务都写一套重复代码会造成大量冗余、难以维护。模板方法模式就是专门处理这种固定流程可变步骤的设计模式。一、概念模板方法模式Template Method Pattern是一种行为型设计模式核心思想定义一个算法的骨架流程将某些步骤的具体实现延迟到子类中使得子类可以不改变整体流程结构即可重定义个别步骤。简单理解父类模板定义整个流程的固定步骤与顺序不允许子类改变骨架。子类实现只重写个别可变步骤流程不变。一句话总结父类定骨架子类填细节。二、核心结构AbstractClass抽象类定义模板方法final防止子类重写定义抽象方法子类必须实现定义钩子方法可选重写定义通用方法公共逻辑ConcreteClass具体子类实现抽象方法完成自身业务逻辑。Client客户端直接调用模板方法。三、Java 代码实现订单支付流程场景所有支付流程都固定为 4 步校验参数固定执行支付不同微信/支付宝/银行卡回调通知固定记录日志固定只有第2步不同完美适合模板方法。1. 抽象类定义模板publicabstractclassAbstractPayTemplate{/** * 模板方法固定支付流程 * final 防止子类篡改流程 */publicfinalvoidpay(StringorderId){checkParam(orderId);// 1.固定doPay(orderId);// 2.可变notify(orderId);// 3.固定log(orderId);// 4.固定}// 固定参数校验privatevoidcheckParam(StringorderId){System.out.println(orderId 参数校验通过);}// 抽象子类必须实现支付逻辑protectedabstractvoiddoPay(StringorderId);// 固定回调通知privatevoidnotify(StringorderId){System.out.println(orderId 支付成功回调通知);}// 固定日志privatevoidlog(StringorderId){System.out.println(orderId 支付日志已记录);}}2. 具体子类微信支付publicclassWechatPayextendsAbstractPayTemplate{OverrideprotectedvoiddoPay(StringorderId){System.out.println(orderId 【微信支付】执行扣款);}}3. 具体子类支付宝支付publicclassAliPayextendsAbstractPayTemplate{OverrideprotectedvoiddoPay(StringorderId){System.out.println(orderId 【支付宝支付】执行扣款);}}4. 客户端调用publicclassClient{publicstaticvoidmain(String[]args){AbstractPayTemplatewechatnewWechatPay();wechat.pay(ORDER_001);System.out.println();AbstractPayTemplatealinewAliPay();ali.pay(ORDER_002);}}输出ORDER_001 参数校验通过 ORDER_001 【微信支付】执行扣款 ORDER_001 支付成功回调通知 ORDER_001 支付日志已记录 ORDER_002 参数校验通过 ORDER_002 【支付宝支付】执行扣款 ORDER_002 支付成功回调通知 ORDER_002 支付日志已记录四、钩子方法Hook—— 让模板更灵活钩子方法是默认空实现/返回true的方法子类可以选择性重写控制流程是否执行某一步。示例增加是否需要回调的钩子publicabstractclassAbstractPayTemplate{publicfinalvoidpay(StringorderId){checkParam(orderId);doPay(orderId);// 钩子控制是否执行通知if(needNotify()){notify(orderId);}log(orderId);}// 钩子方法默认需要通知protectedbooleanneedNotify(){returntrue;}// ... 其他不变}子类可以重写钩子publicclassWechatPayNoNotifyextendsAbstractPayTemplate{OverrideprotectedvoiddoPay(StringorderId){System.out.println(orderId 微信支付(无通知));}// 重写钩子关闭通知OverrideprotectedbooleanneedNotify(){returnfalse;}}五、优缺点优点封装不变部分扩展可变部分流程固定不动细节交给子类。代码复用极强公共逻辑只写一次子类只关注差异。符合开闭原则新增流程只需加子类不改模板。行为由父类控制子类实现结构清晰、易于维护。缺点类数量可能增多每个不同实现一个子类父类若出错会影响所有子类过度使用会导致继承层次复杂六、应用场景凡是流程固定、个别步骤不同的场景支付流程微信/支付宝/银行卡用户注册/登录流程数据导入/导出Excel、CSV、XML消息发送短信、邮件、站内信工作流审批发起、审核、通过、驳回经典源码应用Java ServletdoGet/doPostSpringJdbcTemplate、RestTemplateMyBatisBaseExecutorAndroidActivity生命周期七、模板方法 VS 策略模式模板方法基于继承固定流程骨架步骤可变→ 一套流程多种实现策略模式基于组合算法可互换平级替换→ 多套算法自由切换八、总结模板方法模式 固定流程骨架 可变步骤实现核心父类定流程final子类填细节关键模板方法 抽象方法 钩子方法最适合流程固定、重复代码多、差异小的业务是企业级开发中复用率极高的行为型模式
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2467057.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!