假设我有一个制造调度系统,它由四个部分组成:
有些工厂可以生产某种类型的产品并知道他们是否忙:
interface Factory<ProductType> { void buildProduct(ProductType product); boolean isBusy(); }
有一组不同的产品,它们(除其他外)知道它们是在哪个工厂建造的:
interface Product<ActualProductType extends Product<ActualProductType>> { Factory<ActualProductType> getFactory(); }
然后是一个订购系统,可以生成对要构建的产品的请求:
interface OrderSystem { Product<?> getNextProduct(); }
最后,有一个调度程序可以获取订单并为每个工厂维护一个工作队列:
class Dispatcher { Map<Factory<?>, Queue<Product<?>>> workQueues = new HashMap<Factory<?>, Queue<Product<?>>>(); public void addNextOrder(OrderSystem orderSystem) { Product<?> nextProduct = orderSystem.getNextProduct(); workQueues.get(nextProduct.getFactory()).add(nextProduct); } public void assignWork() { for (Factory<?> factory: workQueues.keySet()) if (!factory.isBusy()) factory.buildProduct(workQueues.get(factory).poll()); } }
免责声明:此代码只是一个示例,并且有几个错误(检查工厂是否存在作为 workQueues 中的键丢失,...)并且非常非最优(可以迭代 entryset 而不是 keyset,...)
现在的问题:
Dispatcher ( ) 中的最后一行factory.buildProduct(workqueues.get(factory).poll());
抛出了这个编译错误:
The method buildProduct(capture#5-of ?) in the type Factory<capture#5-of ?> is not applicable for the arguments (Product<capture#7-of ?>)
我一直在绞尽脑汁思考如何以一种类型安全的方式解决这个问题,但是我的泛型技能在这里让我失望了......
例如,将其更改为以下内容也无济于事:
public void assignWork() {
for (Factory<?> factory: workQueues.keySet())
if (!factory.isBusy()) {
Product<?> product = workQueues.get(factory).poll();
product.getFactory().buildProduct(product);
}
}
即使在这种情况下,应该清楚这没关系......
我想我可以为每个调用的 Product 添加一个“buildMe()”函数factory.buildProduct(this)
,但我很难相信这应该是我最优雅的解决方案。
有任何想法吗?
编辑:
Product 和 Factory 实现的简单示例:
class Widget implements Product<Widget> {
public String color;
@Override
public Factory<Widget> getFactory() {
return WidgetFactory.INSTANCE;
}
}
class WidgetFactory implements Factory<Widget> {
static final INSTANCE = new WidgetFactory();
@Override
public void buildProduct(Widget product) {
// Build the widget of the given color (product.color)
}
@Override
public boolean isBusy() {
return false; // It's really quick to make this widget
}
}