【问题标题】:Method to create similar subclass instances with different parameters创建具有不同参数的相似子类实例的方法
【发布时间】:2018-11-09 06:23:44
【问题描述】:

我目前正在学习 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 employeeIndexCard(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 customerIndexCard(String name, String dni, String adress, String phone, String email) {
    if (Utils.validateDni(dni) && !IndexCard.list.containsKey(dni)) {
        IndexCard.list.put(dni, new FichaCliente(name, adress, phone, email));
    } else {
        throw new InvalidParameterException();
    }
}

有没有什么办法可以重构代码来合并最后两个几乎相同的方法?

【问题讨论】:

  • 对于初学者,请不要为方法提供带有大写字母的类名。这只会造成混乱。
  • 为什么还需要这些方法?只需将验证移至构造函数即可。
  • @Kayaman 如果我将验证移到构造函数中,它不会仍然是重复代码吗?
  • 您可以将公共部分放在超类构造函数中。现在,您可以使用构造函数(它们没有得到验证)或使用您创建的那些方法来创建对象。

标签: java methods refactoring subclass


【解决方案1】:

从我的角度来看,问题是您在这里反对面向对象的设计。您没有提供对 IndexCard 类的访问权限,但它应该如下所示:

public class IndexCard {

    public static Map<String, IndexCard> map = new HashMap<>();

    private String name;
    private String address;
    private String phone;
    private String email;

    // constructor and accessors ommitted
}

首先请不要使用public static 字段并在需要时提供访问器。这可以防止其他类直接更改其状态。你也可以把验证逻辑放在那里:

public class IndexCard {

    private static Map<String, IndexCard> map = new HashMap<>();

    public static void addIndexCard(String dni, IndexCard card) {
        if (Utils.validateDni(dni) && !map.containsKey(dni)) {
            map.put(dni, card);
        } else {
            throw new InvalidParameterException();
        }
    }

    private String name;
    private String address;
    private String phone;
    private String email;

    // constructor and accessors ommitted
}

你可以这样使用类

IndexCard c1 = new EmployeeIndexCard(name, password, adress, phone, email, workArea);
IndexCard.addIndexCard("c1", c1);
IndexCard c2 = new FichaCliente(name, adress, phone, email);
IndexCard.addIndexCard("c2", c2);

【讨论】:

    【解决方案2】:

    由于您的两个类共享一个父类,因此重构代码最自然的方法是将创建实例的责任交给调用者,并接受IndexCard 类型的任何实例:

    public static void addIndexCard(String dni, IndexCard indexCard) {
        if (Utils.validateDni(dni) && !IndexCard.list.containsKey(dni)) {
            IndexCard.list.put(dni, indexCard);
        } else {
            throw new InvalidParameterException();
        }
    }
    

    这样,你可以简单地调用它:

    //add customer index card:
    addIndexCard("dni", new FichaCliente(name, adress, phone, email));
    
    //add employee index card:
    addIndexCard("dni2", new EmployeeIndexCard(name, password, adress, 
                 phone, email, workArea));
    

    【讨论】:

      猜你喜欢
      • 2021-09-24
      • 1970-01-01
      • 2018-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-13
      • 1970-01-01
      相关资源
      最近更新 更多