模板方法 + 策略接口
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);}
}