Skip to content

Instantly share code, notes, and snippets.

@bivas
Created August 14, 2011 09:39
Show Gist options
  • Save bivas/1144743 to your computer and use it in GitHub Desktop.
Save bivas/1144743 to your computer and use it in GitHub Desktop.
Strategy pattern as replacement to instanceof if statements
package com.example.strategy;
public interface Strategy<R> {
public R execute(Object input);
}
public interface ExampleStrategy
extends Strategy<Clas<? extends ExampleStrategy>> {
public void execute();
}
public interface ExampleStrategyHolder
extends StrategyHolder<Class<? extends ExampleStrategy>, ExampleStrategy> {
}
final class ExampleStrategyHolderImpl
extends AbstractStrategyHolder<Class<? extends ExampleStrategy>, ExampleStrategy>
implements ExampleStrategyHolder {
@Inject
ExampleStrategyHolderImpl(final ExampleStrategy... exampleStrategies) {
super(exampleStrategies);
}
@Override
protected ExampleStrategy getDefaultStrategy(final Class<? extends ExampleStrategy> type) {
throw new IllegalStateException("No matching strategy found for type = "
+ type.getSimpleName());
}
}
public class SimpleExampleStrategy
implements ExampleStrategy {
public Class<? extends ExampleStrategy> getDiscriminator() {
return getClass();
}
public void execute() {
throw new NotImplementedException();
}
}
if (obj instanceof Foo) {
doFoo((Foo) obj);
} else if (obj instanceof Bar) {
doBar((Bar) obj);
} else if (...) {
// even more instanceofs switching
} else {
// not always but I've seen it a lot
throw new IllegalArgumentException("missing switch statement");
}
package com.example.strategy;
public interface Strategy<D> {
public D getDiscriminator();
}
package com.example.strategy;
public interface StrategyHolder<D, S extends Strategy<D>> {
public S getStrategy(D type);
}
public abstract class AbstractStrategyHolder<D, S extends Strategy<D>>
implements StrategyHolder<D, S> {
private final Map<D, S> strategies = new HashMap<D, S>();
protected abstract S getDefaultStrategy(D type);
protected AbstractStrategyHolder(final S... strategies) {
for (final S strategy : strategies) {
final D discriminator = strategy.getDiscriminator();
this.strategies.put(discriminator, strategy);
}
}
protected final S findByKey(final Object key) {
return strategies.get(key);
}
@Override
public final S getStrategy(final D type) {
S result = findByKey(type);
if (result == null) {
result = getDefaultStrategy(type);
}
return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment