项目中仅单个属性类型不同的重复类如何避免代码冗余?
嘿,这个问题我之前在项目里也碰到过好多次!当两个类99%的逻辑都一致,就差单个属性的类型不同时,写两份重复代码不仅麻烦,后续维护也容易出问题——改一处得同步改两处,太容易漏了。下面给你几个实用的解决思路,你可以根据自己项目的技术栈和场景来选:
1. 泛型类(最推荐的类型安全方案)
这是处理这种“仅类型差异”场景最优雅的方式,直接把不同的属性类型抽象成泛型参数,一个类就能适配多种类型需求。
举个具体的例子,假设你原来的两个类是这样的:
// 第一个类:ID是String类型 class User { private String id; private String name; // 一堆重复的方法:getter、setter、toString、业务逻辑方法... } // 第二个类:ID是Long类型 class Admin { private Long id; private String name; // 和User完全一样的方法,只是ID类型不同... }
改成泛型类后,只需要写一份通用逻辑:
// 通用父类,用T表示ID的类型 class BaseEntity<T> { private T id; private String name; // 所有通用方法都写在这里 public T getId() { return id; } public void setId(T id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } // 其他通用业务逻辑,比如toString、校验方法等 @Override public String toString() { return "BaseEntity{" + "id=" + id + ", name='" + name + '\'' + '}'; } } // 使用时直接指定类型,甚至可以不用子类(如果不需要扩展额外逻辑) class User extends BaseEntity<String> {} class Admin extends BaseEntity<Long> {}
这样既保留了各自的类型特性(User的ID是String,Admin的是Long),又完全消除了代码冗余,而且类型安全,不会出现转换异常。
2. 继承+抽象属性(适合对泛型不太熟悉的场景)
如果项目团队更习惯用继承的方式,也可以把通用逻辑放到父类,让子类只负责定义那个差异的属性和对应的方法:
abstract class BaseEntity { private String name; // 通用方法都在这里 public String getName() { return name; } public void setName(String name) { this.name = name; } // 抽象方法让子类实现ID的获取和设置 public abstract Object getId(); public abstract void setId(Object id); } class User extends BaseEntity { private String id; @Override public String getId() { return id; } @Override public void setId(Object id) { this.id = (String) id; } } class Admin extends BaseEntity { private Long id; @Override public Long getId() { return id; } @Override public void setId(Object id) { this.id = (Long) id; } }
不过这种方式有个小缺点:类型转换的时候需要小心空指针或类型转换异常,不如泛型那么安全,所以优先推荐泛型方案。
3. 组合模式(适合遗留系统无法修改原有类的场景)
如果这两个类已经是项目里的遗留代码,没法直接修改它们的结构,那可以把重复的逻辑抽成一个公共的辅助类,让两个类通过组合来复用逻辑:
// 抽离所有通用逻辑的辅助类 class EntityUtils { public static void validateName(String name) { if (name == null || name.isEmpty()) { throw new IllegalArgumentException("名称不能为空"); } } public static String generateDisplayName(String prefix, String name) { return prefix + "-" + name; } // 其他通用业务逻辑... } // 原有类保持不变,通用逻辑调用辅助类 class User { private String id; private String name; public void validate() { EntityUtils.validateName(this.name); } public String getDisplayName() { return EntityUtils.generateDisplayName("USER", this.name); } } class Admin { private Long id; private String name; public void validate() { EntityUtils.validateName(this.name); } public String getDisplayName() { return EntityUtils.generateDisplayName("ADMIN", this.name); } }
这种方式不用动原有类的代码,只是把重复的逻辑迁移到公共类里,适合老项目的代码优化。
总结一下:优先选择泛型类,既简洁又类型安全;如果团队对泛型接受度低,再考虑继承方案;如果是遗留代码无法修改,就用组合模式来复用逻辑。
内容的提问来源于stack exchange,提问作者user11595360
相关产品推荐
相关产品推荐

