Search code examples
javainterfaceapi-design

Should callers of an interface (need to) make assumptions about the underlying implementation?


I understand the benefit of Programming to an Interface and the benefit of using an Interface for the return type of a method:

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

I wonder if this is still applicable when the method callers rely on a particular implementation to function correctly? For example,

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;
}

In this case, is it better for getUserIdMap() to return a SortedMap instead of Map so that the method caller does not need to guess the map's underlying implementation? Or is it generally better to return a Map because the method entrySet() belongs to Map?


Solution

  • It would be bad for client code that uses an interface to depend on an implementation detail that is not documented on the interface.

    In your example, the Set and Map interfaces make no guarantees about the order of the elements inside them, so it would be bad for the client to make assumptions about them.

    But this is not a problem in your case, as there are more specific sub-interfaces of Set and Map that do make guarantees about order. They are java.util.SortedSet and java.util.SortedMap. If your client code uses these interfaces, then they are allowed to make assumptions about order.

    TreeSet and TreeMap implement these interfaces, respectively.

    From the Javadoc for SortedMap:

    A Map that further provides a total ordering on its keys.