编程到接口 - 关于实现的假设

时间:2014-04-18 08:01:58

标签: java interface api-design

我理解编程到接口的好处以及将接口用于方法的返回类型的好处:

public List<Integer> getUserIds() {
    return Arrays.asList(1, 2, 3);
}

我想知道当方法调用者依赖特定的实现来正常运行时,这仍然适用吗?例如,

public static void main(final String args[]) {
    final Map<Integer, String> map = getUserIdMap();
    Set<Map.Entry<Integer, String>> entrySet = map.entrySet();

    // print user name in the order of their Ids
    for (final Map.Entry<Integer, String> entry : entrySet) {
        System.out.println(entry.getKey() + ", " + entry.getValue());
    }
}

public static Map<Integer, String> getUserIdMap() {
    final Map<Integer, String> s = new TreeMap<>();
    s.put(3, "Tracer");
    s.put(2, "John");
    s.put(5, "Jane");
    s.put(6, "Jenny");
    s.put(1, "Rob");
    return s;
}

在这种情况下,getUserIdMap()返回SortedMap而不是Map更好,以便方法调用者不需要猜测map的底层实现吗?或者返回Map通常更好,因为方法entrySet()属于Map?

1 个答案:

答案 0 :(得分:4)

使用接口的客户端代码依赖于接口上未记录的实现细节会很糟糕。

在您的示例中,SetMap接口不保证其中元素的顺序,因此客户端对它们做出假设是不好的。

但在您的情况下这不是问题,因为SetMap有更多特定的子接口可以确保订单。它们是java.util.SortedSetjava.util.SortedMap。如果您的客户端代码使用这些接口,则允许 对订单做出假设。

TreeSetTreeMap分别实现这些接口。

来自SortedMap的Javadoc:

  

Map进一步提供总排序   密钥。