Java如何根据商品产地动态创建ShippingCalculator接口实现类?
根据商品产地动态选择运费计算器的实现方案
核心思路
通过工厂模式将运费计算器的选择逻辑集中管理,根据Product的countryOfOrigin字段匹配对应的ShippingCalculator实现类,替代硬编码实例化的方式。
实现步骤
1. 实现工厂类(推荐方案:基于映射缓存)
创建ShippingCalculatorFactory类,用Map缓存不同国家对应的计算器实例,避免重复创建对象,同时便于后续扩展:
import java.util.HashMap; import java.util.Map; public class ShippingCalculatorFactory { // 静态缓存,初始化一次即可复用 private static final Map<String, ShippingCalculator> CALCULATOR_CACHE = new HashMap<>(); // 初始化映射关系:国家代码 -> 对应计算器 static { CALCULATOR_CACHE.put("US", new USAShippingCalculator()); // 可添加更多国家与计算器的映射,比如: // CALCULATOR_CACHE.put("CA", new CanadaShippingCalculator()); } /** * 根据商品产地获取对应的运费计算器 * @param product 商品对象 * @return 匹配的ShippingCalculator,默认返回全球通用计算器 */ public static ShippingCalculator getCalculator(Product product) { String originCountry = product.getCountryOfOrigin(); // 优先匹配缓存中的计算器,无匹配则返回默认的全球计算器 return CALCULATOR_CACHE.getOrDefault(originCountry, new RestofWorldShippingCalculator()); } }
2. 修改业务代码(main方法)
替换硬编码的实例化逻辑,通过工厂类动态获取计算器:
public static void main(String[] args) { // 创建商品 Product product = new Product(); // 动态获取对应产地的运费计算器 ShippingCalculator calculator = ShippingCalculatorFactory.getCalculator(product); // 计算运费 calculator.calculatePrice(product); }
进阶优化方案
如果需要更规范的国家代码管理,可引入枚举类避免字符串硬编码的错误:
// 定义国家代码枚举 public enum CountryCode { US("US"), DEFAULT("DEFAULT"); private final String code; CountryCode(String code) { this.code = code; } // 根据字符串转换为枚举,忽略大小写 public static CountryCode fromString(String inputCode) { for (CountryCode code : CountryCode.values()) { if (code.code.equalsIgnoreCase(inputCode)) { return code; } } return DEFAULT; } }
修改工厂类的匹配逻辑:
public static ShippingCalculator getCalculator(Product product) { CountryCode countryCode = CountryCode.fromString(product.getCountryOfOrigin()); return switch (countryCode) { case US -> new USAShippingCalculator(); default -> new RestofWorldShippingCalculator(); }; }
扩展说明
- 后续新增国家对应的运费计算器时,只需在工厂类的
Map或枚举中添加对应关系,无需修改业务逻辑代码,符合开闭原则。 - 若需要更灵活的配置(比如无需重启服务新增映射),可将国家与计算器的对应关系写入配置文件(如
application.properties),工厂类启动时读取配置初始化缓存。
内容的提问来源于stack exchange,提问作者java12399900
相关产品推荐
相关产品推荐

