Java继承与泛型场景下如何消除Payment实现类重复代码
最优方案:基于泛型的抽象基类复用全部公共逻辑
这种场景下完全不需要用helper类拆分代码,通过泛型抽象基类可以一次性解决所有重复问题,所有业务逻辑只需要维护一份。
首先抽取一个所有支付类共有的抽象基类,绑定Shipment的泛型上界,把原来两个重复类的所有公共逻辑(包括execute的完整流程、三个需要复用的方法)全部迁移到这个基类中:
// 抽象泛型基类,所有处理Shipment的支付类都继承这个类 public abstract class AbstractShipmentPayment<T extends Shipment> extends Payment<T> { // 把原有PaymentA中重复的execute逻辑完整写在这里,参数直接用泛型T @Override public void execute(T shipment) { // 原有的全部业务逻辑,因为T是Shipment的子类,所有通用处理逻辑可以直接执行 } // 原有三个需要复用的私有方法,调整为protected权限,子类可以直接复用 protected void methodA() { // 原PaymentA中methodA的完整实现 } protected void methodB() { // 原PaymentA中methodB的完整实现 } protected void methodC() { // 原PaymentA中methodC的完整实现 } }
迁移完成后,原来的PaymentA和新的PaymentB都变成极薄的实现类,不需要写任何重复代码,只需要指定对应的泛型参数即可:
// 原有PaymentA,直接指定泛型为Shipment,不需要任何重复代码 public class PaymentA extends AbstractShipmentPayment<Shipment> { } // 新写的PaymentB,直接指定泛型为DigitalShipment,不需要任何重复代码 public class PaymentB extends AbstractShipmentPayment<DigitalShipment> { }
该方案相比helper类的优势
- 无上下文传递成本:不需要像helper类那样,把类内的成员变量、方法依赖层层传递给外部类,所有方法的调用链都在类内部完成,避免参数满天飞的冗余代码
- 封装性不受破坏:原来的私有方法调整为protected权限后,子类可以正常复用,不需要为了让helper类调用把方法暴露为public,不破坏原有类的封装边界
- 类型安全有保障:通过泛型上界
T extends Shipment限定所有支付类的处理范围,子类指定具体泛型后,编译期会自动生成匹配的方法签名——PaymentB对外暴露的execute方法天然接收DigitalShipment类型参数,不会丢失类型信息 - 低侵入、易扩展:不需要修改原有
Payment类的上层调用逻辑,后续如果需要新增针对其他Shipment子类的支付实现,只需要继承抽象基类指定对应泛型即可;如果某个支付类需要单独调整逻辑,直接覆写对应方法就行,还可以调用父类的通用逻辑做前后置处理。
补充说明:这种写法不会有泛型擦除导致的类型问题,因为所有通用业务逻辑都是基于Shipment超类实现的,子类传入的具体Shipment子类对象可以直接被通用逻辑处理,运行时不会出现类型转换异常;如果后续需要在子类中对DigitalShipment做专属的扩展处理,再在子类的execute方法里做类型判断或者直接覆写方法即可。如果三个复用的方法并不是所有子类都需要,也可以在抽象基类中将这些方法留空,有需要的子类自行覆写即可,不会强制所有子类实现冗余逻辑。
内容的提问来源于stack exchange,提问作者user641887
相关产品推荐
相关产品推荐

