如何通过创建父类消除Java两个Service类的重复代码?
消除重复代码的两种实用方案
方案一:抽象父类(面向对象继承实现)
这种方式适合后续可能需要扩展子类逻辑的场景,通过继承复用公共代码:
- 创建抽象父类,将重复的
updatePartner逻辑迁移到父类,同时把依赖的成员/方法声明为protected,确保子类可访问:
public abstract class AbstractPartnerService { // 子类共享的依赖,声明为protected protected RoleSql roleSql; protected List<Process> processCheck; // 抽象方法:如果两个子类的createRole逻辑不同,让子类各自实现;若逻辑一致,可直接在父类实现 protected abstract Role createRole(Long mandant, Integer roleCd, Long rID, Long processId, Long processSubId, Long lebId); public void updatePartner(Handle handle, Long mandant, Long rID, Integer roleCd, Long lebId, String user) throws ResourceNotFoundException { // 1: 检查合作伙伴是否已存在 Role roleInDb = roleSql.readActive(mandant, rID, roleCd); if (roleInDb == null) { // 2: 插入新合作伙伴 Process process = processCheck.get(0); Role role = createRole(mandant, roleCd, rID, process.getProcessId(), process.getProcessSubId(), lebId); roleVersioning.insert(role, TecTaskCd.MAN_REGULATION.getValue(), user, SfDate.getTimestampMilli(), ActualizationStatus.FINAL, false); } else { // 3: 更新现有合作伙伴 roleInDb.setPartnerId(lebId); roleVersioning.insert(roleInDb, TecTaskCd.MAN_REGULATION.getValue(), user, SfDate.getTimestampMilli(), ActualizationStatus.FINAL, false); } } }
- 子类继承父类,实现抽象方法并初始化依赖:
public class PartnerOneService extends AbstractPartnerService { // 通过构造方法初始化父类依赖 public PartnerOneService(RoleSql roleSql, List<Process> processCheck) { this.roleSql = roleSql; this.processCheck = processCheck; } @Override protected Role createRole(Long mandant, Integer roleCd, Long rID, Long processId, Long processSubId, Long lebId) { // 这里写PartnerOneService专属的createRole逻辑,若和PartnerTwoService一致可移到父类 return new Role(mandant, roleCd, rID, processId, processSubId, lebId); } }
public class PartnerTwoService extends AbstractPartnerService { public PartnerTwoService(RoleSql roleSql, List<Process> processCheck) { this.roleSql = roleSql; this.processCheck = processCheck; } @Override protected Role createRole(Long mandant, Integer roleCd, Long rID, Long processId, Long processSubId, Long lebId) { // 这里写PartnerTwoService专属的createRole逻辑,若和PartnerOneService一致可移到父类 return new Role(mandant, roleCd, rID, processId, processSubId, lebId); } }
方案二:工具类(静态方法复用)
如果两个Service的逻辑完全无差异,无需扩展,直接用静态工具类封装公共逻辑更简洁:
- 创建工具类,将公共逻辑封装为静态方法,依赖通过参数传入避免耦合:
public class PartnerServiceUtils { public static void updatePartner(RoleSql roleSql, List<Process> processCheck, Function<Object[], Role> createRoleFunc, Handle handle, Long mandant, Long rID, Integer roleCd, Long lebId, String user) throws ResourceNotFoundException { Role roleInDb = roleSql.readActive(mandant, rID, roleCd); if (roleInDb == null) { Process process = processCheck.get(0); Role role = createRoleFunc.apply(new Object[]{mandant, roleCd, rID, process.getProcessId(), process.getProcessSubId(), lebId}); roleVersioning.insert(role, TecTaskCd.MAN_REGULATION.getValue(), user, SfDate.getTimestampMilli(), ActualizationStatus.FINAL, false); } else { roleInDb.setPartnerId(lebId); roleVersioning.insert(roleInDb, TecTaskCd.MAN_REGULATION.getValue(), user, SfDate.getTimestampMilli(), ActualizationStatus.FINAL, false); } } }
- 子类调用工具类方法:
public class PartnerOneService { private static RoleSql roleSql; private static List<Process> processCheck; public static void updatePartner(Handle handle, Long mandant, Long rID, Integer roleCd, Long lebId, String user) throws ResourceNotFoundException { PartnerServiceUtils.updatePartner(roleSql, processCheck, params -> createRole((Long) params[0], (Integer) params[1], (Long) params[2], (Long) params[3], (Long) params[4], (Long) params[5]), handle, mandant, rID, roleCd, lebId, user); } private static Role createRole(Long mandant, Integer roleCd, Long rID, Long processId, Long processSubId, Long lebId) { // 原有createRole逻辑 return new Role(...); } }
public class PartnerTwoService { private static RoleSql roleSql; private static List<Process> processCheck; public static void updatePartner(Handle handle, Long mandant, Long rID, Integer roleCd, Long lebId, String user) throws ResourceNotFoundException { PartnerServiceUtils.updatePartner(roleSql, processCheck, params -> createRole((Long) params[0], (Integer) params[1], (Long) params[2], (Long) params[3], (Long) params[4], (Long) params[5]), handle, mandant, rID, roleCd, lebId, user); } private static Role createRole(Long mandant, Integer roleCd, Long rID, Long processId, Long processSubId, Long lebId) { // 原有createRole逻辑 return new Role(...); } }
关键注意点
- 若
createRole逻辑在两个类中完全一致,直接将其迁移到父类或工具类,无需子类重复实现。 - 继承方式更符合面向对象设计,便于后续扩展;工具类适合逻辑固定、无需扩展的场景。
- 确保父类依赖能被子类正确初始化,可通过构造方法、Setter或依赖注入框架(如Spring)实现。
内容的提问来源于stack exchange,提问作者dgr379
相关产品推荐
相关产品推荐

