同构列表与异构列表

时间:2017-09-23 23:02:01

标签: java java-8

让我们说我正在设计一个名为ToyBox服务的服务,它将一堆形状对象写入数据库并返回对象。它使用的形状是多态的,因此结构如下:

class Shape {
   int id;
}

class Circle extends Shape {
   int radius;
}

class Square extends Shape {
   int length;
}

class ToyBox {
   List<Shape> shapes;
}

现在我的问题是设计这样的服务,对于ToyBox对象来说,更好地保存对Shape对象集合的引用,或者更好的是有一个每种类型的形状的集合(即。 ShapeContainer中的List<Square>, List<Circle>等)? CRUD服务接口也是如此,如果它接受List对象或像这样的容器对象:

class ShapeContainer {
   List<Circle> circles;
   List<Square> squares;
}

服务方法如下:

List<ToyBox> persistToyboxes (List<ToyBox> boxes)

在应用程序的其他地方,我想对正方形和圆形进行不同的处理,所以如果我使用包含List<Shape>对象的ToyBox的方法,我将不得不执行以下操作:

List<Circle> circles = toyBox.getShapes().stream().filter(s -> s instanceOf Circle).collect(Collectors.toList());

试图确定这种系统的最佳设计是什么?

1 个答案:

答案 0 :(得分:2)

答案是......这取决于。

通常,如果ToyBox API将所有形状都视为相同,则它更简单,更清晰(并且API更小)。对它们进行相同处理也意味着您无需更改 API以将Triangle个对象添加到ToyBox API。

但是,如果有一些关于API要求的内容意味着ToyBox需要以完全不同的方式“包含”不同的形状,那么它可能对于ToyBox有不同的API方法。

实现可能应该反映API,但并非绝对必须。例如,您可以为圆形,正方形等的“集合”使用单独的API方法,将它们存储为单个列表对象...并通过一些复杂的过滤或包装来实现这些方法。

最重要的是:您需要了解您的API必须满足的要求......以及(理想情况下)合理预期概括这些要求 1 ..并据此设计。

1 - 例如,您应该预期的ToyBox要求的概括是用户可能希望API能够处理三角形。

顺便说一句,这不起作用:

List<Circle> circles = toyBox.getShapes().stream()
    .filter(s -> s instanceOf Circle)
    .collect(Collectors.toList());

Stream投放的filter类型为Stream<Shape>。你需要做这样的事情:

List<Circle> circles = toyBox.getShapes().stream()
    .filter(s -> s instanceOf Circle)
    .map(s -> (Circle) s)
    .collect(Collectors.toList());

IMO,你最好在ToyBox API中声明一个方法,如下所示:

public List<Circle> getCircles() { ... }

甚至

public <T> List<T> getToysOfType(Class<T> typeClass) { ... }