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 {
@Bean
public OrderValidator regularOrderValidator() {
return RegularOrderStrategies.REGULAR_VALIDATOR;
}
@Bean
public PriceCalculator regularPriceCalculator() {
return RegularOrderStrategies.REGULAR_PRICE_CALCULATOR;
}
@Bean
public OrderSaver regularOrderSaver() {
return RegularOrderStrategies.REGULAR_SAVER;
}
@Bean
public NotificationService regularNotificationService() {
return RegularOrderStrategies.REGULAR_NOTIFIER;
}
@Bean
public OrderValidator vipOrderValidator() {
return VipOrderStrategies.VIP_VALIDATOR;
}
@Bean
public PriceCalculator vipPriceCalculator() {
return VipOrderStrategies.VIP_PRICE_CALCULATOR;
}
@Bean
public OrderSaver vipOrderSaver() {
return VipOrderStrategies.VIP_SAVER;
}
@Bean
public 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);
}
}