可以说我正在设计一个称为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中? CRUD服务接口也是如此,它应该接受List对象或容器对象,如下所示:

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


服务方法如下:

List<Square>, List<Circle>

在应用程序的其他地方,我想对正方形和圆形进行不同的处理,因此如果我使用包含List<ToyBox> persistToyboxes (List<ToyBox> boxes)对象的ToyBox的方法,则必须执行以下操作:

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


只是试图决定哪种系统的最佳设计是什么?

最佳答案

答案是……这取决于。

通常,如果ToyBox API对待所有形状相同,它会更简单,更干净(并且API较小)。对待它们相同也意味着您无需更改API即可将(例如)Triangle对象添加到ToyBox API。

但是,如果有关API要求的内容意味着ToyBox需要以根本不同的方式“包含”不同的形状,则ToyBox具有不同的API方法可能是有意义的。

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

底线是:您需要了解您的API必须满足的要求...以及(理想情况下)这些要求的合理预期概括...并进行相应的设计。



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) { ... }

关于java - 同类列表与异类列表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46385026/

10-10 17:25