如何重构Java中创建相似子类实例的重复方法?
如何重构两个相似的实例创建静态方法?
我正在学习Java,项目里有个父类IndexCard,还有两个子类EmployeeIndexCard和CustomerIndexCard。这两个子类结构很像,但实例变量和构造方法有区别,代码如下:
class EmployeeIndexCard extends IndexCard { public WorkArea workArea ; protected String password; public EmployeeIndexCard(String name, String password, String adress, String phone, String email, String workArea) { super(name, adress, phone, email); this.password = password; this.workArea = WorkArea.valueOf(workArea); } } class CustomerIndexCard extends IndexCard { public CustomerIndexCard(String name, String adress, String phone, String email) { super(name, adress, phone, email); } }
目前我写了两个几乎完全一样的静态方法来创建这两个子类的实例,代码如下:
/** * Create an instance of EmployeeIndexCard. */ public static void createEmployeeIndexCard(String name, String dni, String password, String adress, String phone, String email, String workArea) { if (Utils.validateDni(dni) && !IndexCard.list.containsKey(dni)) { IndexCard.list.put(dni, new EmployeeIndexCard(name, password, adress, phone, email, workArea)); } else { throw new InvalidParameterException(); } } /** * Create an instance of CustomerIndexCard. */ public static void createCustomerIndexCard(String name, String dni, String adress, String phone, String email) { if (Utils.validateDni(dni) && !IndexCard.list.containsKey(dni)) { IndexCard.list.put(dni, new CustomerIndexCard(name, adress, phone, email)); } else { throw new InvalidParameterException(); } }
这两个方法逻辑几乎完全一致,只有创建实例的部分不同,请问有没有办法把它们合并成一个通用方法?
当然可以重构!这两个方法的核心差异就是创建具体子类实例的逻辑,其余的DNI校验、存入Map的逻辑都是完全重复的。我们可以利用Java的函数式接口把创建实例的逻辑抽出来,作为参数传入一个通用方法,这样就能彻底消除重复代码了。
具体实现方案
首先,提取出重复的逻辑,写一个通用的私有方法,它负责完成校验和存入Map的工作,而创建实例的逻辑则通过Supplier<IndexCard>参数传入:
private static void createIndexCard(String dni, Supplier<IndexCard> cardSupplier) { if (Utils.validateDni(dni) && !IndexCard.list.containsKey(dni)) { IndexCard.list.put(dni, cardSupplier.get()); } else { throw new InvalidParameterException(); } }
然后,原来的两个对外方法就可以简化成非常简洁的形式,只需要把对应参数绑定到子类的构造方法上,再把这个构造逻辑包装成Supplier传给通用方法:
public static void createEmployeeIndexCard(String name, String dni, String password, String adress, String phone, String email, String workArea) { createIndexCard(dni, () -> new EmployeeIndexCard(name, password, adress, phone, email, workArea)); } public static void createCustomerIndexCard(String name, String dni, String adress, String phone, String email) { createIndexCard(dni, () -> new CustomerIndexCard(name, adress, phone, email)); }
方案优势
- 减少重复代码:校验和存储逻辑只写一次,后续修改只需要维护这一个通用方法,避免了修改一处要改多个地方的麻烦。
- 扩展性好:如果以后新增其他
IndexCard子类,只需要新增一个类似的简短方法,把构造逻辑传进去就行,不用重复写校验和存储的代码。 - 代码更清晰:对外方法只负责参数传递和构造逻辑,通用方法负责核心的校验和存储,职责划分更明确。
另外,顺便提一下你原代码里的两个小问题:
- 构造方法名要和类名一致:原代码里的
employeeIndexCard和customerIndexCard构造方法名都是小写开头,不符合Java规范,应该改成EmployeeIndexCard和CustomerIndexCard。 - 创建Customer实例时的笔误:原代码里用了
new FichaCliente(...),应该是new CustomerIndexCard(...)。
内容的提问来源于stack exchange,提问作者juan fran
相关产品推荐
相关产品推荐

