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

Java语义相同但分表存储的地址实体如何复用业务逻辑?

解决方案:基于DTO+泛型复用逻辑的简洁实现

针对你遇到的「同字段多地址实体复用业务逻辑」的问题,核心思路是用通用DTO作为中间数据载体,结合泛型转换工具,把业务逻辑和实体类解耦,无需重复编写代码,也不用大规模重构原有业务。

1. 定义通用地址DTO

先创建一个和AddressEntity字段完全对齐的AddressDTO,作为所有地址业务逻辑的处理载体:

public class AddressDTO {
    private String province;
    private String city;
    private String detail;
    // 其他和AddressEntity一致的字段、getter/setter
}

2. 封装泛型转换工具类

用工具类实现DTO与任意地址实体(DeliveryAddressEntity/BillingAddressEntity)的双向转换,推荐用MapStruct(编译期生成转换代码,性能优于反射工具),也可以用Spring的BeanUtils封装泛型方法:

方式一:MapStruct实现(推荐)

@Mapper(componentModel = "spring")
public interface AddressConverter {
    AddressConverter INSTANCE = Mappers.getMapper(AddressConverter.class);

    // DTO转配送地址实体
    DeliveryAddressEntity dtoToDelivery(AddressDTO dto);
    // DTO转账单地址实体
    BillingAddressEntity dtoToBilling(AddressDTO dto);
    // 配送地址实体转DTO
    AddressDTO deliveryToDto(DeliveryAddressEntity entity);
    // 账单地址实体转DTO
    AddressDTO billingToDto(BillingAddressEntity entity);
}

方式二:BeanUtils泛型封装

public class AddressConvertUtils {
    @SuppressWarnings("unchecked")
    public static <T extends AddressEntity> T dtoToEntity(AddressDTO dto, Class<T> entityClass) {
        try {
            T entity = entityClass.getDeclaredConstructor().newInstance();
            BeanUtils.copyProperties(dto, entity);
            return entity;
        } catch (Exception e) {
            throw new RuntimeException("地址转换失败", e);
        }
    }

    public static AddressDTO entityToDto(AddressEntity entity) {
        AddressDTO dto = new AddressDTO();
        BeanUtils.copyProperties(entity, dto);
        return dto;
    }
}

3. 改造原有业务逻辑

把原有基于DeliveryAddressEntity的业务逻辑,迁移到基于AddressDTO处理,核心逻辑只写一次:

// 改造前:仅返回DeliveryAddressEntity
// public DeliveryAddressEntity convertFromOrder(Order order) { ... }

// 改造后:返回通用DTO,核心逻辑复用
public AddressDTO convertFromOrder(Order order) {
    AddressDTO dto = new AddressDTO();
    // 原有赋值逻辑完全复用,只是把对象换成DTO
    dto.setProvince(order.getProvince());
    dto.setCity(order.getCity());
    dto.setDetail(order.getAddressDetail());
    // ...其他字段赋值
    return dto;
}

4. 按需转换为目标实体

在需要具体实体的地方,通过转换工具快速得到对应实体:

// 获取配送地址实体
AddressDTO dto = convertFromOrder(order);
DeliveryAddressEntity deliveryEntity = AddressConverter.INSTANCE.dtoToDelivery(dto);
// 或用BeanUtils工具类:DeliveryAddressEntity deliveryEntity = AddressConvertUtils.dtoToEntity(dto, DeliveryAddressEntity.class);

// 获取账单地址实体
BillingAddressEntity billingEntity = AddressConverter.INSTANCE.dtoToBilling(dto);
// 或用BeanUtils工具类:BillingAddressEntity billingEntity = AddressConvertUtils.dtoToEntity(dto, BillingAddressEntity.class);

5. 兼容原有业务(可选)

如果不想修改原有调用DeliveryAddressEntity的代码,可以新增重载方法,保留原有接口:

// 保留原有方法,内部复用DTO逻辑
public DeliveryAddressEntity convertFromOrder(Order order) {
    AddressDTO dto = convertFromOrderToDto(order);
    return AddressConverter.INSTANCE.dtoToDelivery(dto);
}

// 新增通用DTO转换方法
public AddressDTO convertFromOrderToDto(Order order) {
    // 核心业务逻辑写在这里
    AddressDTO dto = new AddressDTO();
    dto.setProvince(order.getProvince());
    // ...其他赋值
    return dto;
}

// 新增账单地址转换方法
public BillingAddressEntity convertFromOrderToBilling(Order order) {
    AddressDTO dto = convertFromOrderToDto(order);
    return AddressConverter.INSTANCE.dtoToBilling(dto);
}

内容的提问来源于stack exchange,提问作者yorkiepudpud

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 11:57:41