如何判断转换器接口输入参数的对象类型(规避instanceof反模式)
避免使用instanceof处理多类型参数的解决方案
针对你定义的转换器接口接收Object类型参数、需要区分ClaimRecord和CustomerClaim处理业务逻辑的场景,以下是几种替代instanceof的方案:
1. 重载convert方法
直接为每种目标类型定义专属的convert方法,利用Java的方法重载机制自动匹配类型,完全无需手动判断:
interface ClaimConverter { List<ClaimsTOObject> convert(ClaimRecord claimRecord); List<ClaimsTOObject> convert(CustomerClaim customerClaim); }
实现该接口时,分别为两个方法编写对应类型的业务转换逻辑即可。调用方只需传入对应类型的对象,JVM会自动分发到正确的方法,符合面向对象的多态设计原则。
2. 让实体类实现统一转换接口
如果有权限修改ClaimRecord和CustomerClaim的代码,可以定义一个统一的转换接口,让两个实体类分别实现该接口,将转换逻辑内聚到实体自身:
// 定义统一转换接口 interface ClaimsConvertible { List<ClaimsTOObject> toClaimsTOObjectList(); } // 让ClaimRecord实现转换接口 class ClaimRecord implements ClaimsConvertible { @Override public List<ClaimsTOObject> toClaimsTOObjectList() { // 编写ClaimRecord专属的转换逻辑 return new ArrayList<>(); } } // 让CustomerClaim实现转换接口 class CustomerClaim implements ClaimsConvertible { @Override public List<ClaimsTOObject> toClaimsTOObjectList() { // 编写CustomerClaim专属的转换逻辑 return new ArrayList<>(); } }
此时转换器接口可以直接接收ClaimsConvertible类型参数,避免使用Object:
interface ClaimConverter { default List<ClaimsTOObject> convert(ClaimsConvertible convertible) { return convertible.toClaimsTOObjectList(); } }
这种方式将转换逻辑与实体类绑定,符合单一职责原则,也彻底消除了类型判断的需求。
3. 策略模式+类型映射
如果无法修改ClaimRecord和CustomerClaim的代码,可采用策略模式,将不同类型的转换逻辑封装为独立策略类,通过类型映射表动态分发:
// 定义转换策略接口 interface ConversionStrategy { List<ClaimsTOObject> convert(Object claimObject); } // ClaimRecord对应的转换策略 class ClaimRecordStrategy implements ConversionStrategy { @Override public List<ClaimsTOObject> convert(Object claimObject) { ClaimRecord record = (ClaimRecord) claimObject; // 编写ClaimRecord的转换逻辑 return new ArrayList<>(); } } // CustomerClaim对应的转换策略 class CustomerClaimStrategy implements ConversionStrategy { @Override public List<ClaimsTOObject> convert(Object claimObject) { CustomerClaim claim = (CustomerClaim) claimObject; // 编写CustomerClaim的转换逻辑 return new ArrayList<>(); } } // 转换器实现类 class ClaimConverterImpl implements ClaimConverter { // 初始化类型与策略的映射表 private static final Map<Class<?>, ConversionStrategy> STRATEGY_MAP = new HashMap<>(); static { STRATEGY_MAP.put(ClaimRecord.class, new ClaimRecordStrategy()); STRATEGY_MAP.put(CustomerClaim.class, new CustomerClaimStrategy()); } @Override public List<ClaimsTOObject> convert(final Object claimObject) { ConversionStrategy strategy = STRATEGY_MAP.get(claimObject.getClass()); if (strategy == null) { throw new IllegalArgumentException("不支持的索赔类型: " + claimObject.getClass().getName()); } return strategy.convert(claimObject); } }
这种方式通过getClass()获取类型后匹配策略,替代了instanceof判断,后续新增类型时只需添加新的策略类并更新映射表,符合开闭原则,代码扩展性更强。
内容的提问来源于stack exchange,提问作者J.Klimov
相关产品推荐
相关产品推荐

