当前位置: 首页 > news >正文

模板方法 + 策略接口

1.模板:控制业务主体处理流程

2.策略:提高扩展性

示例:订单处理流程

我们有多种订单类型(如普通订单、VIP订单、促销订单),它们的处理流程大致相同,但某些步骤的行为不同:

验证订单
计算价格
保存订单
发送通知

我们可以将这些步骤定义为策略接口,然后在一个通用的模板类中进行调用。

第一步:定义策略接口

@FunctionalInterface
interface OrderValidator {boolean validate(OrderContext context);
}@FunctionalInterface
interface PriceCalculator {double calculatePrice(OrderContext context);
}@FunctionalInterface
interface OrderSaver {void save(OrderContext context);
}@FunctionalInterface
interface NotificationService {void notifyCustomer(OrderContext context);
}

第二步:定义上下文对象

class OrderContext {public String orderId;public String customerType;public double basePrice;public OrderContext(String orderId, String customerType, double basePrice) {this.orderId = orderId;this.customerType = customerType;this.basePrice = basePrice;}
}

 第三步:定义模板逻辑类(使用策略组合)

class OrderProcessor {private final OrderValidator validator;private final PriceCalculator priceCalculator;private final OrderSaver orderSaver;private final NotificationService notificationService;public OrderProcessor(OrderValidator validator,PriceCalculator priceCalculator,OrderSaver orderSaver,NotificationService notificationService) {this.validator = validator;this.priceCalculator = priceCalculator;this.orderSaver = orderSaver;this.notificationService = notificationService;}// 模板方法:编排订单处理流程public void processOrder(OrderContext context) {// 校验订单if (!validator.validate(context)) {System.out.println("订单验证失败,取消处理");return;}// 计算价格double finalPrice = priceCalculator.calculatePrice(context);System.out.println("最终价格: " + finalPrice);// 保存订单orderSaver.save(context);// 发送通知notificationService.notifyCustomer(context);}
}

第三步:定义模板逻辑类(使用策略组合)

实现1:普通客户订单

class RegularOrderStrategies {public static OrderValidator validator = ctx -> {System.out.println("普通客户订单验证...");return true;};public static PriceCalculator calculator = ctx -> {System.out.println("普通客户价格计算...");return ctx.basePrice * 1.0;};public static OrderSaver saver = ctx -> System.out.println("普通订单已保存");public static NotificationService notifier = ctx -> System.out.println("普通客户通知已发送");
}

 实现2:VIP客户订单(享受折扣)

class VipOrderStrategies {public static OrderValidator validator = ctx -> {System.out.println("VIP订单验证...");return "VIP".equals(ctx.customerType);};public static PriceCalculator calculator = ctx -> {System.out.println("VIP价格计算(9折)...");return ctx.basePrice * 0.9;};public static OrderSaver saver = ctx -> System.out.println("VIP订单已保存");public static NotificationService notifier = ctx -> System.out.println("VIP客户通知已发送");
}

第五步:测试主类

public class Main {public static void main(String[] args) {OrderContext regularOrder = new OrderContext("1001", "Regular", 100.0);OrderContext vipOrder = new OrderContext("1002", "VIP", 100.0);// 普通订单处理器OrderProcessor regularProcessor = new OrderProcessor(RegularOrderStrategies.validator,RegularOrderStrategies.calculator,RegularOrderStrategies.saver,RegularOrderStrategies.notifier);// VIP订单处理器OrderProcessor vipProcessor = new OrderProcessor(VipOrderStrategies.validator,VipOrderStrategies.calculator,VipOrderStrategies.saver,VipOrderStrategies.notifier);System.out.println("处理普通订单:");regularProcessor.processOrder(regularOrder);System.out.println("\n处理VIP订单:");vipProcessor.processOrder(vipOrder);}
}

输出示例:

处理普通订单:
普通客户订单验证...
普通客户价格计算...
最终价格: 100.0
普通订单已保存
普通客户通知已发送处理VIP订单:
VIP订单验证...
VIP价格计算(9折)...
最终价格: 90.0
VIP订单已保存
VIP客户通知已发送

这种设计的优点:
优势                    描述
高度解耦             每个步骤由独立的策略接口实现,模块清晰
运行时可变          可在运行时动态更换策略行为
支持组合扩展      可根据不同业务需求自由组合策略
便于测试             每个策略可单独单元测试
符合开闭原则     扩展新订单类型无需修改已有代码

种设计的优点
缺点                   描述
复杂度提升        相比传统的继承式模板方法,策略组合的方式引入更多的类、接口和依赖注入。

默认行为缺失    如果每个步骤都必须传入策略实现,可能会导致重复编写一些通用逻辑(例如日志记录、异常处理)。当然可以通过封装默认策略来缓解。

配置和初始化复杂    在大型项目中,如果策略很多,初始化和装配这些策略的代码会变得冗长,需要配合工厂模式、Spring IOC 容器等来管理依赖。

改进版

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class OrderProcessor {private static final Logger logger = LoggerFactory.getLogger(OrderProcessor.class);private final OrderValidator validator;private final PriceCalculator priceCalculator;private final OrderSaver orderSaver;private final NotificationService notificationService;// 使用Builder模式简化构造private OrderProcessor(Builder builder) {this.validator = builder.validator;this.priceCalculator = builder.priceCalculator;this.orderSaver = builder.orderSaver;this.notificationService = builder.notificationService;}public void processOrder(OrderContext context) {try {logger.info("开始处理订单: {}", context.getOrderId());if (!validator.validate(context)) {logger.warn("订单验证失败,取消处理");return;}double finalPrice = priceCalculator.calculatePrice(context);logger.info("最终价格: {}", finalPrice);orderSaver.save(context);notificationService.notifyCustomer(context);} catch (Exception e) {logger.error("订单处理失败", e);throw new RuntimeException("订单处理失败", e);}}public static class Builder {private OrderValidator validator;private PriceCalculator priceCalculator;private OrderSaver orderSaver;private NotificationService notificationService;public Builder setValidator(OrderValidator validator) {this.validator = validator;return this;}public Builder setPriceCalculator(PriceCalculator priceCalculator) {this.priceCalculator = priceCalculator;return this;}public Builder setOrderSaver(OrderSaver orderSaver) {this.orderSaver = orderSaver;return this;}public Builder setNotificationService(NotificationService notificationService) {this.notificationService = notificationService;return this;}public OrderProcessor build() {// 提供默认实现if (validator == null) {this.validator = ctx -> true; // 默认通过验证}if (priceCalculator == null) {this.priceCalculator = ctx -> ctx.getBasePrice(); // 默认原价}if (orderSaver == null) {this.orderSaver = ctx -> logger.info("默认保存逻辑"); // 默认保存逻辑}if (notificationService == null) {this.notificationService = ctx -> logger.info("默认通知逻辑"); // 默认通知逻辑}return new OrderProcessor(this);}}
}

Spring 配置与注入

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class OrderStrategyConfig {@Beanpublic OrderValidator regularOrderValidator() {return RegularOrderStrategies.REGULAR_VALIDATOR;}@Beanpublic PriceCalculator regularPriceCalculator() {return RegularOrderStrategies.REGULAR_PRICE_CALCULATOR;}@Beanpublic OrderSaver regularOrderSaver() {return RegularOrderStrategies.REGULAR_SAVER;}@Beanpublic NotificationService regularNotificationService() {return RegularOrderStrategies.REGULAR_NOTIFIER;}@Beanpublic OrderValidator vipOrderValidator() {return VipOrderStrategies.VIP_VALIDATOR;}@Beanpublic PriceCalculator vipPriceCalculator() {return VipOrderStrategies.VIP_PRICE_CALCULATOR;}@Beanpublic OrderSaver vipOrderSaver() {return VipOrderStrategies.VIP_SAVER;}@Beanpublic NotificationService vipNotificationService() {return VipOrderStrategies.VIP_NOTIFIER;}
}

测试主类

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class Main {public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(OrderStrategyConfig.class);OrderProcessor.Builder builder = new OrderProcessor.Builder();// 处理普通订单OrderContext regularOrder = new OrderContext("1001", "Regular", 100.0);builder.setValidator(context.getBean("regularOrderValidator", OrderValidator.class)).setPriceCalculator(context.getBean("regularPriceCalculator", PriceCalculator.class)).setOrderSaver(context.getBean("regularOrderSaver", OrderSaver.class)).setNotificationService(context.getBean("regularNotificationService", NotificationService.class));OrderProcessor regularProcessor = builder.build();regularProcessor.processOrder(regularOrder);System.out.println("\n处理VIP订单:");// 处理VIP订单OrderContext vipOrder = new OrderContext("1002", "VIP", 100.0);builder.setValidator(context.getBean("vipOrderValidator", OrderValidator.class)).setPriceCalculator(context.getBean("vipPriceCalculator", PriceCalculator.class)).setOrderSaver(context.getBean("vipOrderSaver", OrderSaver.class)).setNotificationService(context.getBean("vipNotificationService", NotificationService.class));OrderProcessor vipProcessor = builder.build();vipProcessor.processOrder(vipOrder);}
}

http://www.lqws.cn/news/562195.html

相关文章:

  • glog使用详解和基本使用示例
  • 数据结构:顺序表
  • Lua现学现卖
  • Java代码阅读题
  • 06-three.js 创建自己的缓冲几何体
  • 某音Web端消息体ProtoBuf结构解析
  • 【网络安全】网络安全中的离散数学
  • 机器学习算法-K近邻算法-KNN
  • BUUCTF [ACTF新生赛2020]music 1
  • SpringMVC系列(五)(响应实验以及Restful架构风格(上))
  • 【学习】《算法图解》第七章学习笔记:树
  • [论文阅读] 软件工程 | 微前端在电商领域的实践:一项案例研究的深度解析
  • Linux软件的安装目录
  • 【面板数据】省级电商指数与地级市电子商务交易额数据集(1990-2022年)
  • OpenLayers 下载地图切片
  • Docker安装MinIO
  • 概述-4-通用语法及分类
  • 【go】初学者入门环境配置,GOPATH,GOROOT,GOCACHE,以及GoLand使用配置注意
  • 案例开发 - 日程管理系统 - 第一期
  • Redis 实现分布式锁
  • 【C++进阶】--- 继承
  • 鸿蒙 Grid 与 GridItem 深度解析:二维网格布局解决方案
  • 复杂驱动开发-TLE9471的休眠流程与定时唤醒
  • Python训练营-Day44-预训练模型
  • Java中的异常及异常处理
  • JDK17的GC调优
  • SpringCloud Stream 使用
  • Youtube双塔模型
  • 第27篇:SELinux安全增强机制深度解析与OpenEuler实践指南
  • eTools 开源发布