juan fran
juan fran

Reputation: 359

Method to create similar subclass instances with different parameters

I am currently learning Java. I have a project with a superclass (IndexCard), with two subclasses (EmployeeIndexCard and CustomerIndexCard). Both subclasses are very similar, but they are different from each other for their instance variables, and thus, by its constructors.

Here they are:

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);
    }
}

I wonder what am I doing wrong, since to create instances of these classes I have created two very similar methods:

/**
 * 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();
    }
}

Is there any way to restructure the code to merge this two last methods that are almost identical?

Upvotes: 3

Views: 594

Answers (2)

Glains
Glains

Reputation: 2873

The problem is, from my perspective, that you are working against object oriented design here. You did not provide access to the class IndexCard, but it should look something like this:

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
}

First of all please do not use public static fields and provide accessors if needed. This prevents other classes from changing its state directly. You can also put the validation logic there:

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
}

You can use the class like this

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);

Upvotes: 1

ernest_k
ernest_k

Reputation: 45339

Since your two classes share a parent, the most natural way to refactor the code is to live the responsibility of creating the instance to the caller, and accept any instance of the IndexCard type:

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();
    }
}

This way, you can call it simply:

//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));

Upvotes: 3

Related Questions