Java中的泛型策略模式

Java中的泛型策略模式,java,oop,generics,Java,Oop,Generics,因此,我试图创建一个带有泛型函数的接口,该函数将被子类重写,但我找不到一种方法来实现这一点 我认为一段代码将更加明确: interface Agent<A extends Agent<A>> { <W extends World> Iterable<Action<A,W>> percepts(W world); <W extends World> void takeAction(Action<A,W&g

因此,我试图创建一个带有泛型函数的接口,该函数将被子类重写,但我找不到一种方法来实现这一点

我认为一段代码将更加明确:

interface Agent<A extends Agent<A>> {
    <W extends World> Iterable<Action<A,W>> percepts(W world);
    <W extends World> void takeAction(Action<A,W> action, W world);
}

abstract class StrategistAgent<A extends StrategistAgent<A>> implements Agent<A> {
    abstract public <W extends World> AgentStrategy<A,W> getStrategy();
    abstract public <W extends World> void setStrategy(AgentStrategy<A,W> strategy);

    @Override
    <W extends World> Iterable<Action<A,W>> percepts(W world) {
        return getStrategy().run(this, world);
    }
}

interface AgentStrategy<A extends StrategistAgent<A>, W extends World> {
    Iterable<Action<A,W>> run(A agent, W world);
    void init(A agent, W world);
}
接口代理{
易感知觉(W世界);
无效行动(行动行动,W世界);
}
抽象类代理实现代理{
抽象公共代理策略getStrategy();
抽象公共战略(代理战略);
@凌驾
Iterable感知(W世界){
返回getStrategy().run(this,world);
}
}
接口代理策略{
Iterable run(代理,W world);
void init(代理,W world);
}
错误:类型AgentStrategy中运行的方法(A,World)不适用于参数(AgentStrategy,W)

但我不会写:

StrategistAgent<A extends StrategistAgent<A>, W extends World>
agent

编辑:好,我遵照马克·彼得斯的建议,删除了setStrategy方法。现在应该可以工作了。

对,所以问题是,正如您现在可能已经发现的那样,没有任何迹象表明,在发生错误的地方,
这个
A
的一个实例。这就是当我说泛型真的不是为这种自引用类型而设计的时候我的意思

不过,您的设计中还存在其他问题。首先,设置策略时接受的
W
可能与调用
percept
时得到的
W
完全不同

那么,你的前进方向是什么?好吧,我再次指出,这取决于你的胶水代码,创建代理和策略并将它们组合在一起的东西

由于粘合代码很可能知道它所处理的是哪种类型的代理和策略,因此您甚至可能无法从抽象的
setStrategy
中获益。一旦它不是抽象的,您就可以在每个子类中处理它

实际上,子类所需要的只是一个受保护的方法
getStrategy
。如果您强制所有子类都提供该功能,那么您还可以强制它们返回
A

abstract class StrategistAgent<A extends StrategistAgent<A>> implements Agent<A> {
    protected abstract <W extends World> AgentStrategy<A,W> getStrategy();
    protected abstract A getSelf();

    @Override
    public <W extends World> Iterable<Action<A,W>> percepts(W world) {
        return this.<W>getStrategy().run(getSelf(), world);
    }
}
抽象类代理实现代理{
受保护的抽象代理策略getStrategy();
受保护的抽象对象是getSelf();
@凌驾
公众可感知(W世界){
返回这个.getStrategy().run(getSelf(),world);
}
}

所以这是一个解决方案。不过,我必须多想一想,才能想出一个更优雅的版本。

删除有问题的类型约束?似乎在代理和代理之间的类型约束中存在循环依赖关系,您需要以某种方式打破这个循环。好的,我缩小了问题的范围:percepts是可以的,但它不能调用run,这应该是正确的。。。替换Iterable run(A代理,W world);Iterable run的代理战略(战略家代理,W world);显示错误:类型不匹配:无法从Iterable转换为Iterable为什么需要在代理的特定子类上键入策略?如果你扩展一下你真正想要完成的事情,这会很有帮助,因为这绝对不是泛型的设计目的。什么意思不是泛型的设计目的?我想有可能为世界上任何一个代理商写一份战略。我相信如果可能的话,一个策略实例应该分配给多个代理…@Tug:Generics并不是用来作为自我引用类型的黑客,这就是我的意思。这似乎有点像你有一个锤子,现在看到螺丝钉钉。这方面的“粘合”代码(构建具体代理并用策略填充它们的代码)在哪里?它如何从泛型中获益?啊,很好的发现!很高兴知道我的术语并没有完全脱节。