Template method pattern with implementation specific parameter type
I often get into situation when I'd like to use template method pattern, but the template method expects a different type of a parameter, like this:
public abstract class AbstractFoo {
public void process(TypeA a, TypeB b) {
//do common processing
if (b == null) {
doProcess(a);
} else if(a == null) {
doProcess(b);
}
}
public abstract void doProcess(TypeA a);
public abstract void doProcess(TypeB b);
}
This doesn't look good. One of the supplied paramaters would have to be null and all services would have to implement dummy doProcess methods for other types. Is there any better pattern for this? How do you deal w开发者_如何学Pythonith this ? I don't want to use constructor because these services are spring beans. Also the same problem applies to Strategy pattern.
public abstract class AbstractFoo<T> {
public void process(T a) {
//do common processing
doProcess(a);
}
protected abstract void doProcess(T a);
}
public class Person extends AbstractFoo<Person> {
@Override
protected void doProcess(Person p) {
p.draw();
}
}
public class Car extends AbstractFoo<Car> {
@Override
protected void doProcess(Car c) {
c.draw();
}
}
You're right that it definitely isn't a template method pattern, but I'm not sure exactly what you're trying to do. Maybe you're after the factory pattern:
interface Foo {
boolean isA();
boolean isB();
...
}
class ProcessorFactory {
public Processor getProcessor(Foo foo) {
if (foo.isA()) {
return new AProcessor();
}
if (foo.isB()) {
return new BProcessor();
}
...
}
}
As for constructors, all of my spring beans have constructors that express their dependencies. What's wrong with that?
I think using a Wrapper class can solve this problem. Wrapper class can be a simple Holder entity. You can even consider encapsulating your application specific properties in the wrapper class (more on lines of a Context). With this approach you only need one process method and the sub classes will only process the Message if it has the correct type. To avoid code duplication you can also do that checking in your abstract class. See following example,
public class Context {
private Object body;
public Context(Object obj) {
body = obj;
}
public Object getBody() {
return body;
}
}
public abstract class AbstractFoo {
public void process(Context ctx) {
//do common processing
if (canProcess(ctx)) {
doProcess(ctx.getBody());
}
}
protected abstract <T extends Object> boolean canProcess(T obj);
protected abstract <T extends Object> void doProcess(T obj);
}
精彩评论