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

如何重构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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:15:31