Moonlit Moonlit - 2 months ago 6
Java Question

Get rid of if statements to improve code design

How can I improve the design of the code below:

class Foo {
public Configuration configure() {
return new Configuration().withPropertyA().withPropertyB();
}
}

class Configuration{


private boolean propertyA = false;
private boolean propertyB = false;

public Configuration withPropertyA() {
this.propertyA = true;
return this;
}

public Configuration withPropertyB() {
this.propertyB = true;
return this;
}

public boolean hasPropertyA() {
return this.propertyA;
}

public boolean hasPropertyB() {
return this.propertyB;
}

...
}

class Client{

public void someMethod(Configuration config) {
if (config.hasPropertyA() {
doStuffA();
}
if (config.hasPropertyB() {
doStuffB();
}
//...
}

}


I.e., the Configuration class holds some flags for the caller (
Client
) that tell to the caller which "things" need to be configured. The Client knows what to do for each of the flags if they are set. I want to get rid of the if statement in
Client
as well as of the concept of simply setting boolean flags in the
Configuration
instance. Can you suggest a more "generic" and object oriented approach to this?

kind regards

Answer

You may use the Strategy pattern. Each If becomes a Strategy, which implements doStuff, with its own logic. When a property (A, B...) is set, you add the strategy to the list. You simply need to loop on the strategies and execute them, without any ifs:

public class Foo  {
    public Configuration configure() {
        return new Configuration().withPropertyA().withPropertyB();
    }
}

class Configuration {
    Set<StuffStrategy> strategies = new HashSet<StuffStrategy>();

    public Configuration withPropertyA() {
        strategies.add(new PropertyAStrategy());
        return this;
    }

    public Configuration withPropertyB() {
        strategies.add(new PropertyBStrategy());
        return this;
    }

    public void executeStrategies() {
        for (StuffStrategy strategy : strategies) {
            strategy.doStuff();
        }
    }
}

interface StuffStrategy {
    public void doStuff();
}
class PropertyAStrategy implements StuffStrategy {
    @Override
    public void doStuff() {
    }
}

class PropertyBStrategy implements StuffStrategy {
    @Override
    public void doStuff() {
    }
}

class Client {
    public void someMethod(Configuration config) {
        config.executeStrategies();
    }
}
Comments