You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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模式更适合当前场景,原因如下:

  1. 贴合业务逻辑结构:当前业务是「固定基础逻辑+部分产品追加定制处理」,Template Method的核心就是定义算法骨架(基础逻辑),将可变步骤延迟到子类实现,完美匹配这种“固定流程+局部定制”的需求。子类只需关注自身定制逻辑,无需重复实现基础逻辑,复用性更高。
  2. 实现简洁直观:基于继承的实现方式,产品B、C的子类仅需重写doGetStatus方法,代码量少、结构清晰。而Decorator模式需要定义接口、抽象装饰类,每个装饰类还要持有被装饰对象,实现繁琐,对于当前单一维度(仅产品类型)的定制,没必要引入装饰器的复杂结构。
  3. 流程可控性强:基类明确了「先执行基础逻辑,再执行定制逻辑」的固定流程,调用方直接使用对应产品的Service即可,维护和调试更简单。

其他更优建议

如果未来产品类型会频繁扩展,**策略模式(Strategy Pattern)**是更优选择,它的扩展性和解耦性更强:

策略模式实现示例

  1. 定义策略接口:
public interface ProductStatusStrategy {
    String customizeStatus(String baseStatus, Product product);
}
  1. 实现各产品策略类:
// 产品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;
    }
}
  1. 统一服务类管理策略:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 06:20:15