具有特定于实现的参数类型的模板方法模式

发布于 2024-11-23 19:01:57 字数 529 浏览 2 评论 0原文

当我想使用模板方法模式时,我经常遇到这种情况,但模板方法需要不同类型的参数,如下所示:

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

这看起来不太好。提供的参数之一必须为 null,并且所有服务都必须为其他类型实现虚拟 doProcess 方法。有没有更好的模式呢?你如何处理这个问题?我不想使用构造函数,因为这些服务是 spring bean。同样的问题也适用于策略模式。

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 with this ? I don't want to use constructor because these services are spring beans. Also the same problem applies to Strategy pattern.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夜巴黎 2024-11-30 19:01:57
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();
    }
}
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();
    }
}
不爱素颜 2024-11-30 19:01:57

你是对的,它绝对不是模板方法模式,但我不确定你到底想做什么。也许您正在追求工厂模式:

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

至于构造函数,我的所有 spring bean 都有表达其依赖关系的构造函数。这有什么问题吗?

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?

剩一世无双 2024-11-30 19:01:57

我认为使用Wrapper类可以解决这个问题。包装类可以是一个简单的 Holder 实体。您甚至可以考虑将应用程序特定的属性封装在包装类中(更多关于上下文的行)。使用这种方法,您只需要一个处理方法,并且子类只会处理具有正确类型的消息。为了避免代码重复,您还可以在抽象类中进行检查。请参阅以下示例,

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

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文