I’m adding a line spacer to various GUI screens depending on screen resolution. Currently in the various GUI classes there are calls to a method which returns the screen resolution and adds a new spacer depending on screen resolution. Depending on the class type the value of the SpacerField can change. Is there a design pattern I can use to refactor the code so that there are less conditionals and it is more object orientated ?
Class A:
if(getScreenResolution() == 360){
add(new SpacerField(15));
}
if(getScreenResolution() == 460){
add(new SpacerField(5));
}
Class B:
if(getScreenResolution() == 360){
add(new SpacerField(35));
}
if(getScreenResolution() == 460){
add(new SpacerField(15));
}
Possible solution –
add(new SpacerUtils.getSpacerField(this));
public static SpacerUtils {
static {
int screenRes = getScreenRes();
}
public static SpacerField getSpacerField(Object obj) {
if(obj instanceof GuiScreen1 && screenRes == 360){
return new SpacerField(25);
}
else if(obj instanceof GuiScreen2 && screenRes == 360){
return new SpacerField(35);
}
}
}
Something like this ?
For each possible spacer value I need to add a new implementation, in this case I just have one – SpacerSmall.
Caller -
Spacer spacer = new SpacerSmall();
if(resolution == 360){
add(new SpacerField(0 , spacer.getSpacerValue()));
}
Interface -
public interface Spacer {
public int getSpacerValue();
}
Implementation -
public class SpacerSmall implements Spacer{
public int getSpacerValue() {
return 15;
}
}
You need only one class. Classes should differ on behavior not on data, you shouldn’t even make two different classes based on different data. This brings useless class proliferation. The different configuration could be provided in a constructor.
This is configuration, it’s a good practice to create those instances with a Dependency Injection framework and inject the instances where necessary with setters method.
Even if you don’t use a dependency injection framework you can do yourself for now and migrate in the future. Here is how:
And when you use it: