在重构Java项目以使用合成而没有继承时,我仍然存在一个问题,即对集合进行了多态排序。
继承示例:
public class AClass
{
private List<OneClassOfManyThatRequireSortedInstances> unsortedList;
public List<OneClassOfManyThatRequireSortedInstances> getSortedList()
{
List<OneClassOfManyThatRequireSortedInstances> sortedList = new ArrayList(this.unsortedList);
Collections.sort(sortedList, SuperClassOfManyThatRequireSortedInstances.orderComparator);
return sortedList;
}
}
现在,重构后;类OneClassOfManyThatRequireSortedInstances
不再继承自抽象SuperClassOfManyThatRequireSortedInstances
,但Collections.sort()
期望相互比较的实例。
重构这个的最佳方法是什么?
为了完整;我已经添加了比较器实现并进一步澄清了问题。
public class SuperClassOfManyThatRequireSortedInstances
{
private int order;
public static final Comparator<SuperClassOfManyThatRequireSortedInstances> orderComparator = new Comparator<SuperClassOfManyThatRequireSortedInstances>()
{
public int compare(SuperClassOfManyThatRequireSortedInstances o1, SuperClassOfManyThatRequireSortedInstances o2)
{
if ((o1 == null) && (o2 == null))
{
return 0;
}
if (o1 == null)
{
return -1;
}
if (o2 == null)
{
return 1;
}
return (new Integer(o1.getOrder()).compareTo(new Integer(o2
.getOrder())));
}
};
public int getOrder()
{
return this.order;
}
public void setOrder(int order)
{
this.order = order;
}
}
问题的关键在于,在重构到合成后,OneClassOfManyThatRequireSortedInstances
不再"is a"
SuperClassOfManyThatRequireSortedInstances
,因此代码被破坏了。
许多类OneClassOfManyThatRequireSortedInstances
不再拥有共同的父级。因此,只有Collections.sort()
的单个实现,Comparator
不能在这些类中使用。
像OneClassOfManyThatRequireSortedInstances
这样的类现在改为拥有SuperClassOfManyThatRequireSortedInstances
成员; "has a"
关系。{{1}}
答案 0 :(得分:4)
假设有两个类Car
和Train
。您可以创建一个类似
public interface SpeedProvider {
int getSpeed();
}
然后,Car
和Train
都会实现SpeedProvider
接口
public class Car implements SpeedProvider {
int maxSpeed = 220;
@Override
public int getSpeed() {
return maxSpeed;
}
}
public class Train implements SpeedProvider {
int maxSpeed = 300;
@Override
public int getSpeed() {
return maxSpeed;
}
}
最后,您可以实施一个比较两个Comparator
SpeedProvider
public class VehicleComparator implements Comparator<SpeedProvider> {
@Override
public int compare(SpeedProvider o1, SpeedProvider o2) {
/* ... */
return 0;
}
}
答案 1 :(得分:1)
这个问题没有意义。 Comparator<T>
用于构图。使用继承时的替代方法是Comparable<T>
。你的问题又回到了前面。
答案 2 :(得分:0)
您可以通过接口获得合同,您可以根据特定的字段集(如使用的超类)返回某些排序方法。然后你可以有一个进行排序计算的类和另一组根据不同的字段/组合进行排序的类。
然后你可以简单地传递一个Comparator的实例,它将执行所需的排序,它将检查instanceof ...你可以选择抛出错误或日志,如果没有实现特定的接口,则静静地返回默认值。