我用接口和抽象类重构了保险系统,架构师看完给我涨了薪!

最近我在重构公司的保险系统,遇到个头疼的问题:不同类型的保险(医疗险、意外险、寿险)既有共同的业务逻辑(比如保单生成、理赔申请),又有各自独特的规则(比如理赔材料要求、费率计算方式)。

一开始我全用if else堆逻辑,代码像坨shi。后来用接口和抽象类重构后,代码瞬间清爽了,架构师看完直接给我涨了20%的绩效!今天就用这个真实案例,给你讲透接口和抽象类的实战用法。

场景还原:保险系统的痛点

公司的保险系统支持三种险种:

  • 医疗险:理赔时需要医院诊断证明、发票;
  • 意外险:理赔时需要事故证明、伤残鉴定;
  • 寿险:理赔时需要死亡证明、受益人关系证明。

原来的代码是这样的:

public class InsuranceService {
    public void claim(String insuranceType, ClaimRequest request) {
        if ("HEALTH".equals(insuranceType)) {
            // 医疗险理赔逻辑:校验医院诊断证明、发票
            System.out.println("校验医疗险理赔材料:诊断证明、发票");
            System.out.println("计算医疗险理赔金额...");
            System.out.println("医疗险理赔审批中...");
        } else if ("ACCIDENT".equals(insuranceType)) {
            // 意外险理赔逻辑:校验事故证明、伤残鉴定
            System.out.println("校验意外险理赔材料:事故证明、伤残鉴定");
            System.out.println("计算意外险理赔金额...");
            System.out.println("意外险理赔审批中...");
        } else if ("LIFE".equals(insuranceType)) {
            // 寿险理赔逻辑:校验死亡证明、受益人关系证明
            System.out.println("校验寿险理赔材料:死亡证明、受益人关系证明");
            System.out.println("计算寿险理赔金额...");
            System.out.println("寿险理赔审批中...");
        }
    }
}

问题很明显:

  1. 每新增一种险种,就要改这个if else,违反开闭原则;
  2. 三种险种的理赔流程有重复代码(比如计算金额、审批),没有复用;
  3. 代码可读性差,逻辑分散,维护困难。

用接口重构:定义“规矩”

首先想到用接口,因为所有保险都得能“理赔”:

// 保险接口:定义理赔规矩
public interface Insurance {
    // 校验理赔材料(具体怎么校验,由实现类决定)
    boolean validateClaimDocuments(List<Document> documents);
    
    // 计算理赔金额(不同险种算法不同)
    BigDecimal calculateClaimAmount(ClaimRequest request);
    
    // 提交理赔申请
    ClaimResult submitClaim(ClaimRequest request);
}

// 医疗险实现
public class HealthInsurance implements Insurance {
    @Override
    public boolean validateClaimDocuments(List<Document> documents) {
        System.out.println("校验医疗险理赔材料:诊断证明、发票");
        return documents.stream()
                .anyMatch(doc -> "诊断证明".equals(doc.getType()) || "发票".equals(doc.getType()));
    }

    @Override
    public BigDecimal calculateClaimAmount(ClaimRequest request) {
        System.out.println("按医疗险规则计算理赔金额...");
        return request.getAmount().multiply(new BigDecimal("0.8")); // 假设报80%
    }

    @Override
    public ClaimResult submitClaim(ClaimRequest request) {
        // 提交理赔申请的通用逻辑
        System.out.println("医疗险理赔申请已提交,等待审批...");
        return new ClaimResult("PENDING", "审批中");
    }
}

// 意外险和寿险的实现类似,省略...

这样改完后,新增险种只需要实现Insurance接口,不用改原有代码。但问题来了:三种险种的理赔申请提交逻辑(submitClaim方法)几乎一样,却要在每个实现类里重复写,这不是浪费吗?

用抽象类重构:提供“模板”

这时候抽象类就派上用场了!我们发现,虽然三种险种的理赔材料校验、金额计算不同,但理赔申请提交的流程是一样的(提交申请→生成理赔号→进入审批流程)。

于是我们把通用逻辑抽到抽象类里:

// 抽象保险类:实现通用逻辑,留下差异化部分给子类
public abstract class AbstractInsurance implements Insurance {
    // 提交理赔申请的通用逻辑(模板方法)
    @Override
    public ClaimResult submitClaim(ClaimRequest request) {
        // 1. 先校验材料(具体怎么校验由子类实现)
        if (!validateClaimDocuments(request.getDocuments())) {
            return new ClaimResult("REJECTED", "材料不全");
        }
        
        // 2. 计算理赔金额(具体怎么计算由子类实现)
        BigDecimal amount = calculateClaimAmount(request);
        
        // 3. 生成理赔号(通用逻辑)
        String claimNumber = generateClaimNumber();
        
        // 4. 记录理赔日志(通用逻辑)
        logClaim(request, amount);
        
        // 5. 返回结果(通用逻辑)
        System.out.println("理赔申请已提交,理赔号:" + claimNumber);
        return new ClaimResult("PENDING", "审批中");
    }
    
    // 生成理赔号(通用方法,子类不用重写)
    private String generateClaimNumber() {
        return UUID.randomUUID().toString().replace("-", "").substring(0, 10);
    }
    
    // 记录理赔日志(通用方法,子类不用重写)
    private void logClaim(ClaimRequest request, BigDecimal amount) {
        System.out.println("记录理赔日志:" + request.getPolicyNumber() + ",金额:" + amount);
    }
}

// 医疗险只需继承抽象类,实现差异化方法
public class HealthInsurance extends AbstractInsurance {
    @Override
    public boolean validateClaimDocuments(List<Document> documents) {
        System.out.println("校验医疗险理赔材料:诊断证明、发票");
        return documents.stream()
                .anyMatch(doc -> "诊断证明".equals(doc.getType()) || "发票".equals(doc.getType()));
    }

    @Override
    public BigDecimal calculateClaimAmount(ClaimRequest request) {
        System.out.println("按医疗险规则计算理赔金额...");
        return request.getAmount().multiply(new BigDecimal("0.8"));
    }
}

// 意外险和寿险类似,省略...

这样一来,三种险种的理赔申请流程被统一管理,重复代码大幅减少。子类只需要专注于自己特有的逻辑(校验材料、计算金额),通用的流程交给抽象类处理。

终极优化:抽象类+接口组合使用

实际项目中,我们还可以进一步优化:

  1. 用接口定义行为:比如所有保险都得能“理赔”“续保”;
  2. 用抽象类实现通用逻辑:比如理赔申请的提交流程、续保的基本逻辑;
  3. 具体险种继承抽象类并实现接口:兼顾灵活性和复用性。
// 保险接口:定义所有保险必须有的行为
public interface Insurance {
    boolean validateClaimDocuments(List<Document> documents);
    BigDecimal calculateClaimAmount(ClaimRequest request);
    ClaimResult submitClaim(ClaimRequest request);
    boolean renewPolicy(Policy policy);
}

// 抽象保险类:实现通用逻辑
public abstract class AbstractInsurance implements Insurance {
    // 实现提交理赔申请的通用流程
    @Override
    public ClaimResult submitClaim(ClaimRequest request) {
        // 通用流程...
    }
    
    // 实现续保的通用逻辑
    @Override
    public boolean renewPolicy(Policy policy) {
        System.out.println("处理续保基本流程...");
        if (policy.isExpired()) {
            return false;
        }
        // 生成新保单、计算新保费等通用逻辑
        return true;
    }
}

// 医疗险:继承抽象类,实现自己特有的逻辑
public class HealthInsurance extends AbstractInsurance {
    @Override
    public boolean validateClaimDocuments(List<Document> documents) {
        // 医疗险特有的材料校验
    }
    
    @Override
    public BigDecimal calculateClaimAmount(ClaimRequest request) {
        // 医疗险特有的金额计算
    }
}

总结:保险项目里的接口与抽象类

  • 接口:像“保险行业标准”,规定所有保险产品必须能“理赔”“续保”,但具体怎么做,由各保险公司(实现类)自己定。
  • 抽象类:像“保险产品模板”,把所有保险都有的通用流程(比如理赔申请的提交步骤、续保的基本逻辑)实现好,子类只需要实现自己特有的部分。

口诀

  • 有“共同行为规范”,用接口;
  • 有“共同实现逻辑”,用抽象类;
  • 既有“规范”又有“通用实现”,接口+抽象类一起上!

下次遇到类似的业务场景,记得用这个套路重构代码——架构师看了会流泪,产品经理改需求时你能笑出声!

如果你是刚开始学习java,或者刚开始从事java行业,有很多的问题都可以关注微信公众号“java学长”,一个致力于打造免费指导学习java高薪就业的公益平台!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@佳瑞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值