为 public API 公开集合或集合

Exposing Collection or Set for public API

据说针对接口而不是特定类型进行编码是一种很好的做法。换句话说,我们在创建 API.

时公开通用接口而不是特定实现

例如:

public Collection<Model> getUniqueModels();
public void setUniqueModels(Collection<Model> modelCollection);

但我的问题是,如果我想让消费者知道我只会 return 一组独特的模型,即所有模型都会不同。

public Set<Model> getUniqueModels();
public void setUniqueModels(Set<Models> modelSet);

这是创建 publc API 的糟糕方法吗?如果我使用集合一,而消费者发送了一份无法使用的重复模型列表怎么办?

使用Set接口还是符合接口编程的原则。只要它定义了您打算使用的集合的语义,就没有问题,在这种情况下,集合中的所有元素都是唯一的。 CollectionSet都是接口,但后者让消费者明白没有重复。

设计 "lenient" public API 的一个好方法是让类型在您 return 的事情上尽可能具体,并且尽可能宽容尽你所能接受的事情。

在这种特殊情况下,您应该 return 一个 Set<Model> 并接受 Collection<Model>,并理解任何重复项将被忽略:

public Set<Model> getUniqueModels();
public void setUniqueModels(Collection<Model> modelSet);

甚至

public void setUniqueModels(Collection<? extends Model> modelSet);

像这样的 API 会告诉用户他们不会从 getter 的模型中获得任何重复项,但它会接受 setter 中其他类型的集合,如果您的 API 的用户更喜欢以其他方式验证唯一性(例如,通过使用确保唯一性的查询从数据库中提取 List<Model>)。

what if the consumer sends a list of duplicates unknowingly?

有两种方法可以解决这个问题:您可以默默地忽略它,或者您可以验证并引发异常。

第一种方法(即忽略重复项)通常就足够了:这就是 Java API 的做法,例如,在从集合构造 HashSet<T> 时.与其让用户到处制作唯一集,不如制作一次唯一集,然后让他们将副本传递给你。

然而,即使是第二种方法也比接受 Set<Model> 给用户更多的灵活性,因为它让用户决定是否使集合独一无二。

公开 Set 接口是可以接受的——毕竟这仍然是一个接口,而不是具体的 class。 暴露特定的具体 class 是不好的做法,例如 HashSet ,但是你可以暴露 and消费了Set。我认为没有必要只暴露最高级别的接口。