Interface-methods vs util-methods

Abstract

Do methods belong in an interface or in a utility class? This post describes my vision about this question.

Introduction

A few weeks ago there was a discussion on a blog about the oo’ness of utility classes. Some people claimed that utility classes are not object oriented, because the static utility method is not executed on the object itself. Instead, this object is passed as an argument to a utility-method. I think this view limits good oo-design, because calling someObject.someMethod() is not the holy grail of object oriented programming (just like subclassing).

2 Different types of methods

For this discussion I distinguish 2 different types of methods:

  1. implementation dependent methods like List.size(). The size method depends on a specific implementation of the List interface, how it is determined; maybe an internal counter is used, maybe an iteration over the elements of the list is done.
  2. implementation independent methods. These methods are build on top of other interface methods, without having any implementation specific knowledge. An example of such a method is the List.indexOf(Object). This method can use the List.get(int) and the List.size() methods to find the first index. There is not always a clear separation which methods are dependent and which ones are not; you could always create a List implementation where the indexOf method uses a hashtable for better search-performance.

Possible locations

The best location for an implementation dependent method is adding it to the interface. If it is placed outside that interface, you would have to break encapsulation, and in most cases this is something you want to prevent. The implementation independent method has more options of being placed:

  1. add them to the interface. An example is the already mentioned List.indexOf(Object) method. A technique often used, is creating an abstract super class that contains the implementation independent methods. The subclass only needs to implement the implementation dependent methods. An example of this technique is the AbstractList and the ArrayList. The ArrayList extend the AbstractList and only needs to implement the implementation dependent methods like get(int) and size().
  2. add them to a utility class. An example is the Collection.sort(List)

Which location is best

The question remains which location is best. Like most interesting questions, there is no black and white answer. If you add a new method to an interface, it could be that you are breaking implementing classes; especially when the interface is very public and you don’t have control over the implementations. Although using an abstract superclass can prevent some damage, you have no way of knowing if a class implements the interface directly.

Methods in utility classes don’t have this problem, because adding a new utility-method won’t break any implementations. Another important advantage of using a utility class is that it helps to prevent bloated interfaces. You can even use multiple utility classes to group related methods. I must confess that this technique is not something I have used very often, but on certain occasions it was very helpful. But utility classes are not without problems either; they are more difficult to use because it is less obvious where functionality can be found. The lack of code completion for these methods doesn’t help either. The last disadvantage I can think of is that they can’t make use implementation specific functionality.

Which location is best, needs to be decided on a case by case basis. But in a lot of cases interfaces are quite simple and adding new methods to the interface is often the easiest solution.

Advertisements

3 Responses to Interface-methods vs util-methods

  1. It’s actually quite hard to judge.

    Anyone can implement an ‘isEmpty()’ method in a utility class, if they have a collection that has a ‘size()’ method, but most of the time it would be possible for isEmpty() to be better implemented by the collection. E.g., for a LinkedList, size() would typically be O(n) and isEmpty() would be O(1).

    Therefore, when you are choosing whether to put a method in an interface or a utility class, you need to decide these two things:

    1. If I put it in the interface, would the code for the method look any different between implementations?

    2. If the answer to number 1 is “no”, and the method is not in a public API, then you can go ahead and put the method in a utility class, safe in the knowledge that if your answer to number 1 ever changes, you can easily refactor. If the method is not in a public API, then refactoring becomes expensive. Still, you can avoid your main interface becoming bloated.

    Let’s imagine for a moment that Collections.sort would be better if it could vary in implementation (maybe you have some List implementations that keep themselves sorted anyway, so sorting is a no-op, etc.). If you don’t want to change your List interface to add ‘sort’, then you can create your own interface, that either extends or composes List. I’ll go with the composed way here, because there’s less finger-typing involved. And I’ll ignore generics, because there’s no preview button, and I don’t want them treated as HTML..

    interface SortableList
    {
    void sort();
    List getOriginal();
    }

    The other way would have SortableList extends List, which takes more code to implement but less to use. Swings and roundabouts.

    So for a public API, a new interface might be a better option, *if and when* a static method becomes unsatisfactory.

  2. Dhanji says:

    I am actually of the opposite school–I strongly believe static utility classes are antipatternistic in a domain api. While it is ok for some basic framework-style uses (static factories, string-trimmers, etc.), it makes much more sense to me to go this way:

    interface CollectionSorter {
    void sort(List list);
    }

    Then I can provide a variety of sorting impls behind this list, without binding to ugly static calls (impls), or worse polluting my domain object (List) with corollary functionality. This means if my sorting needs ever change I do not have to refactor the client code to change the sort algorithm. Spring uses this philosophy everywhere, and needless to say it makes testing a lot easier (mocks).

    The Builder and Visitor design patterns come to mind. Note that most of Collections and Arrays methods are factories.

    Congratulations on your new blog peter =)

  3. pveentjer says:

    Hi Dhanji,
    I think we agree on the fact that not all logic should be placed in the subject (the object that is being used). We only differ in the mechanism that should be used to place the methods.
    The problem with your approach is that you will have to inject dependencies into your objects for every function-container and that is going to complicate development (and spring configuration).
    So I would not recommend replacing all utility classes with this approach. But in some situations this also is a very good solution.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: