访客和战略模式中的泛型类型

时间:2013-03-31 18:30:23

标签: java oop design-patterns

我正在尝试创建一个Visitor<T>,为对象的instanceof返回某个strategy。 它已经有效了,但我无法获得Generics类型安全。我错过了以下代码:

class Base;
class Foo extends Base;
class Bar extends Base;

interface Visitor<T> {
    T visit (Foo foo);
    T visit (Bar bar);
}

interface Strategy<T> {
    void action(T obj);
}

class FooStrategy implements Strategy<Foo> {
    @Override
    void action(Foo foo) {
        //perform strategy action on foo
    }
}

//References to generic type Strategy<T> should be parameterized
class MyVisitor implements Visitor<Strategy> {

    //References to generic type Strategy<T> should be parameterized
    @Override
    Strategy visit(Foo foo) {
        return new FooStrategy();
    }

    //References to generic type MyStrategy<T> should be parameterized
    @Override
    Strategy visit(Bar bar) {
        return new BarStrategy();
    }
}

在类MyVisitor中,eclipse一直抱怨应该Strategy<T>参数化。制作这个通用构造typesafe时我缺少什么?

更新

我想这样用:

        Visitor<Strategy> visitor = new MyVisitor();
        Strategy strat = drawable.accept(visitor);

        //use the strategy
        Base object; //may be a Foo or Bar or whatever
        strat.action(object);

2 个答案:

答案 0 :(得分:2)

您可以将? extends Base放入type参数,以表明它是您不关心的任何类型的策略,但它必须是Base的子类。

class MyVisitor implements Visitor<Strategy<? extends Base>> {
  @Override
  Strategy<? extends Base> visit(Foo foo) {
    return new FooStrategy();
  }
  @Override
  Strategy<? extends Base> visit(Bar bar) {
    return new BarStrategy();
  }
}

    Visitor<Strategy<? extends Base>> visitor = new MyVisitor();
    Strategy<? extends Base> strat = drawable.accept(visitor);

但是,您不能调用这样的策略:

    //use the strategy
    Base object; //may be a Foo or Bar or whatever
    strat.action(object);  // <--- error.

因为动作方法有效地具有

的签名
<U extends Base> void action(U object);

即。参数的类型可能需要 Base的任意子类,并且唯一可以传递给Base的任意子类的类型是null

要解决这个问题,只需让FooStrategy和BarStrategy实现Strategy<Base>

class FooStrategy implements Strategy<Base> { void action(Base obj) { ... } }
class BarStrategy implements Strategy<Base> { void action(Base obj) { ... } }

class MyVisitor implements Visitor<Strategy<Base>> {
  @Override
  Strategy<Base> visit(Foo foo) {
    return new FooStrategy();
  }
  @Override
  Strategy<Base> visit(Bar bar) {
    return new BarStrategy();
  }
}

Visitor<Strategy<Base>> visitor = new MyVisitor();
Strategy<Base> strat = drawable.accept(visitor);

Base object;
strat.action(object);

答案 1 :(得分:0)

这不是访客。即使它是,这对一个人来说也不是正确的用法。访客使用双重发送;这没有。