java确保成员之间的兼容性,使用低绑定泛型
比如说,我正在构建一个通用的AssemblyLine
类,它可以获取物理对象,测量它们,将它们放在硬纸盒中,然后对它们进行礼品包装。我希望用户能够提供他们自己的物体测量策略(可能有些人关心物体的总体积,有些人只关心物体的最长尺寸)以及他们自己的盒子选择策略(因为用户最清楚他们想要使用哪种纸箱)
如果AssemblyLine
能够接受对物理对象的超类进行操作的测量策略和框选择策略,那就太好了。毕竟,如果用户有一个适用于各种Dessert
的度量策略,我们应该让他们在AssemblyLine<Cake>
和AssemblyLine<Pie>
中使用相同的策略,对吗
让我们从测量策略开始:
public interface PhysicalObjectMeasurementStrategy<T> {
Measurement measureObject(T object);
}
很简单,而且我认为没有争议。接下来,我们要为框选择策略定义一个接口。这可能是我的第一个错误,但现在让我们继续:
public interface CardboardBoxSelectionStrategy<T> {
CardboardBoxSize chooseCardboardSizeForObject(T object, PhysicalObjectMeasurementStrategy<? super T> measurementStrategy);
}
我的想法是,我希望能够为我们可以测量的任何东西选择一个盒子。如果我们有一个选择馅饼盒的策略和一个可以处理任何甜点的测量策略,那么能够在多个地方使用甜点测量策略就很好了
现在,将所有这些整合成一条装配线:
public class AssemblyLine<T> {
private final PhysicalObjectMeasurementStrategy<? super T> measurementStrategy;
private final CardboardBoxSelectionStrategy<? super T> boxSelectionStrategy;
// ...
public void giftWrapObject(final T physicalObject) {
// Here's where things fall apart:
boxSelectionStrategy.chooseCardboardSizeForObject(physicalObject, this.measurementStrategy);
// ...
}
}
问题就我所知(这可能是完全错误的!),我们无法保证measurementStrategy
和boxSelectionStrategy
都是指T
的同一个超类,实际上可能是指不相关的超类(或接口)。例如,我们可能会遇到以下情况:
PhysicalObjectMeasurementStrategy<Cylindrical>
CardboardBoxSelectionStrategy<Edible>
AssemblyLine<Cake>
这两种策略都适用于装配线,但由于并非所有Cylindrical
对象都是Edible
(反之亦然),因此将度量策略传递给框选择策略没有意义
那么,说到这里:在声明或构造AssemblyLine
时,有没有一种好的方法来确保我们讨论的是相同的或至少是兼容的超类?如果没有,还有其他解决这个问题的好方法吗(这个问题有名字吗?),或者我需要重新考虑设计,并可能在装配线上使用不太灵活的组件
谢谢
# 1 楼答案
一种方法是为测量和盒子选择策略使用独立的类型参数,它们是兼容的:
另一种方法可能是允许将任何可以测量对象的测量策略传递给框选择策略:
或者,可以先测量对象,然后将测量值传递给框选择策略
我不知道这个问题有没有名字