简体   繁体   中英

JAVA design a factory for enum's

Decide on a set of enum's of similar structure, dynamically based on a parameter.

example :

public enum StateUS {
 CALIFORNIA(Sacramento,...)
 private String capital;
 ...
}

public enum StateIN {
 KARNATAKA(Bangalore,...)
 private String capital;
 ...
}

public enum Countries {
US, IN
}

// in a different class
public <> getStates(Countries country){
// to return Country.US.equals(country) ?  StateUS : StateIN 
// so the return enum class can be used for business logic.
}

Based on the value of enum Countries , need to decide whether to use StateUS or StateIN .

what's the best way to implement the same using enum's ? Can a factory class be implemented to decide on enum ?

Solution I can think of is to convert enum's into classes and create a factory class. But this is a tedious procedure and too much of boiler code to get enum functionalities (ex : comparisons).

This is how I would do it. You would need to add a State interface:

public interface State {
    String getCapital();
}

Then make both StateIN and StateUS implement such an Interface:

public enum StateIN implements State {
    KARNATAKA("Bangalore");

    private String capital;

    StateIN(String capital) {
        this.capital = capital;
    }

    @Override
    public String getCapital() {
        return capital;
    }
}
public enum StateUS implements State {
    CALIFORNIA("Sacramento");

    private String capital;

    StateUS(String capital) {
        this.capital = capital;
    }

    @Override
    public String getCapital() {
        return capital;
    }
}

And in your Countries enum you would need to take advantage of the State interface to allow the following:

public enum Countries {
    IN(Arrays.asList(StateIN.values())),
    US(Arrays.asList(StateUS.values()));

    private List<? extends State> states;

    Countries(List<? extends State> states) {
        this.states = states;
    }

    public List<? extends State> getStates() {
        return states;
    }
}

And now you can implement your getStates(Countries country) as you would like to have it:

public static List<? extends State> getStates(Countries country){
    return country.getStates();
}

Below is an example so that you can check that this actually works:

public static void main(String[] args) {
    System.out.println("States");
    System.out.println("IN: " + getStates(Countries.IN));
    System.out.println("US: " + getStates(Countries.US));
    System.out.println("");
    System.out.println("States Capital");
    System.out.println("IN: " + getStates(Countries.IN).stream().map(State::getCapital).collect(Collectors.toList()));
    System.out.println("US: " + getStates(Countries.US).stream().map(State::getCapital).collect(Collectors.toList()));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM