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