Reputation: 908
I'm refactoring some legacy system written in Java, and I came across a problem with an enum constructor.
I have an enum class like this (just an example):
public enum Signal{
ON(new InButton()),
OFF(new OutButton())
private final Button button;
Signal(Button button) {
this.button = button;
}
}
InButton and OutButton extends the Button interface.
The enum values are accessed for the first time using Signal.Values() method. (Also, in one of the Button method, I have a code that uses the enum, such as activateButton(Signal.ON))
While refactoring the code, I wanted to create a new constructor for Button that express it dependency, such as Button(String input).
The problem is that I don't know how to pass the new parameters to the enum button field. What is the right way to deal with this situation? Is this enum should be used at all?
Clarification after Jean Logeart question: InButton
and OutButton
also have a constructor with a String
arguments.
I'd rather avoid it to be initialize to null because than it could create other problems.
Basically this question is how to mimic a=f(x) using java syntax. Most of the time I can do:
In this case I can't do it.
Upvotes: 0
Views: 1598
Reputation: 43391
I suggest not having the enums know about the buttons at all. Just have them enumerate the possible signals, and put the job of mapping signal->button somewhere else:
Function<Signal, Button> signalToButton = ...
That will also make it easier to inject different buttons for testing; for instance, you can inject a mocked Button that confirms that it was our wasn't pressed.
As far as using that mapping in your code: you can "install" a mapping to some static field, or, better yet, provide it as a constructor argument to any code that needs it. Dependency injection is very helpful for the latter option, but that may be a bigger change.
Upvotes: 2
Reputation: 53819
Two main options.
First one, InButton
and OutButton
also have a constructor with a String
argument in which case you need to provide a String
when instanciating:
public class InButton extends Button {
public InButton(String s) {
super(s);
}
}
// ...
public enum Signal{
ON(new InButton("in"))
// ...
}
Second option, InButton
and OutButton
are instanciated with a specific String
in which case no refactoring is necessary in the enum
:
public class InButton extends Button {
public InButton() {
super("in"); // default value
}
}
// ...
public enum Signal{
ON(new InButton()) // same as before
// ...
}
Upvotes: 0