Template Method与Decorator模式选型:Java订单状态场景分析
问题场景与实现方案
业务背景
我用Java开发,需要根据产品类型获取订单状态,所有产品类型共享以下基础逻辑:
protected String getStatus(ProductType productType, Result result) { if (result.isSuccess()) { return "SUCCESS"; } else if (result.getPaymentMethod().equals("TRANSFER")) { return "WAITING_CONFIRMATION"; } else { return "WAITING_PAYMENT"; } }
不同产品类型存在自定义逻辑:
- 产品类型为“A”时,无需修改上述逻辑
- 若基础逻辑返回“SUCCESS”且产品类型为“B”,需调用另一服务核查产品发放状态
- 若基础逻辑返回“SUCCESS”且产品类型为“C”,需调用合作伙伴服务
已实现的两种方案
Template Method模式实现
public class BaseProductStatusService { public String getStatus(Result result, Product product) { String status; if (result.isSuccess()) { status = "SUCCESS"; } else if (result.getPaymentMethod().equals("TRANSFER")) { status = "WAITING_CONFIRMATION"; } else { status = "WAITING_PAYMENT"; } return doGetStatus(status, product); } protected String doGetStatus(String status, Product product) { return status; } } // 产品A无需单独实现类,直接使用基类即可 public class ProductBStatusService extends BaseProductStatusService { @Override protected String doGetStatus(String status, Product product) { if (status.equals("SUCCESS")) { return this.checkProductIssuance(product); } return status; } } public class ProductCStatusService extends BaseProductStatusService { @Override protected String doGetStatus(String status, Product product) { if (status.equals("SUCCESS")) { return this.checkStatusToPartner(product); } return status; } }
Decorator模式实现
public interface ProductStatusService { String getStatus(Result result, Product product); } public class DefaultProductStatusService implements ProductStatusService { public String getStatus(Result result, Product product) { String status; if (result.isSuccess()) { status = "SUCCESS"; } else if (result.getPaymentMethod().equals("TRANSFER")) { status = "WAITING_CONFIRMATION"; } else { status = "WAITING_PAYMENT"; } return status; } } public abstract class ProductStatusServiceDecorator implements ProductStatusService { private ProductStatusService productStatusService; public ProductStatusServiceDecorator(ProductStatusService productStatusService) { this.productStatusService = productStatusService; } @Override public String getStatus(Result result, Product product) { return this.productStatusService.getStatus(result, product); } } // 产品A无需单独实现类,直接使用DefaultProductStatusService即可 public class ProductBStatusServiceDecorator extends ProductStatusServiceDecorator { public ProductBStatusServiceDecorator(ProductStatusService productStatusService) { super(productStatusService); } @Override public String getStatus(Result result, Product product) { String status = super.getStatus(result, product); if (status.equals("SUCCESS")) { return this.checkProductIssuance(product); } return status; } } public class ProductCStatusServiceDecorator extends ProductStatusServiceDecorator { public ProductCStatusServiceDecorator(ProductStatusService productStatusService) { super(productStatusService); } @Override public String getStatus(Result result, Product product) { String status = super.getStatus(result, product); if (status.equals("SUCCESS")) { return this.checkStatusToPartner(product); } return status; } }
疑问
请问哪种方案更适合该场景?原因是什么?是否有其他更优建议?
方案分析与建议
哪种方案更适合?
Template Method模式更适合当前场景,原因如下:
- 贴合业务逻辑结构:当前业务是「固定基础逻辑+部分产品追加定制处理」,Template Method的核心就是定义算法骨架(基础逻辑),将可变步骤延迟到子类实现,完美匹配这种“固定流程+局部定制”的需求。子类只需关注自身定制逻辑,无需重复实现基础逻辑,复用性更高。
- 实现简洁直观:基于继承的实现方式,产品B、C的子类仅需重写
doGetStatus方法,代码量少、结构清晰。而Decorator模式需要定义接口、抽象装饰类,每个装饰类还要持有被装饰对象,实现繁琐,对于当前单一维度(仅产品类型)的定制,没必要引入装饰器的复杂结构。 - 流程可控性强:基类明确了「先执行基础逻辑,再执行定制逻辑」的固定流程,调用方直接使用对应产品的Service即可,维护和调试更简单。
其他更优建议
如果未来产品类型会频繁扩展,**策略模式(Strategy Pattern)**是更优选择,它的扩展性和解耦性更强:
策略模式实现示例
- 定义策略接口:
public interface ProductStatusStrategy { String customizeStatus(String baseStatus, Product product); }
- 实现各产品策略类:
// 产品A策略(默认无定制) public class ProductAStrategy implements ProductStatusStrategy { @Override public String customizeStatus(String baseStatus, Product product) { return baseStatus; } } // 产品B策略 public class ProductBStrategy implements ProductStatusStrategy { @Override public String customizeStatus(String baseStatus, Product product) { if ("SUCCESS".equals(baseStatus)) { return checkProductIssuance(product); } return baseStatus; } } // 产品C策略 public class ProductCStrategy implements ProductStatusStrategy { @Override public String customizeStatus(String baseStatus, Product product) { if ("SUCCESS".equals(baseStatus)) { return checkStatusToPartner(product); } return baseStatus; } }
- 统一服务类管理策略:
public class ProductStatusService { private static final Map<ProductType, ProductStatusStrategy> STRATEGY_MAP = new HashMap<>(); static { STRATEGY_MAP.put(ProductType.A, new ProductAStrategy()); STRATEGY_MAP.put(ProductType.B, new ProductBStrategy()); STRATEGY_MAP.put(ProductType.C, new ProductCStrategy()); } public String getStatus(Result result, Product product) { // 执行基础逻辑 String baseStatus; if (result.isSuccess()) { baseStatus = "SUCCESS"; } else if ("TRANSFER".equals(result.getPaymentMethod())) { baseStatus = "WAITING_CONFIRMATION"; } else { baseStatus = "WAITING_PAYMENT"; } // 执行对应产品的定制逻辑 ProductStatusStrategy strategy = STRATEGY_MAP.get(product.getType()); return strategy.customizeStatus(baseStatus, product); } }
策略模式的优势:
- 完全遵循开闭原则:新增产品类型时只需添加新策略类,无需修改原有服务代码;
- 策略类完全解耦:各产品逻辑独立维护,避免继承带来的耦合问题;
- 灵活性更高:支持运行时动态切换策略(若有需求)。
如果当前产品类型较少且短期内不会大幅增加,Template Method足够简洁好用;若未来产品类型会频繁扩展,策略模式的扩展性和灵活性更具优势。
内容的提问来源于stack exchange,提问作者CherryBelle
相关产品推荐
相关产品推荐

