Do you really need a List?
One of the most important aspects of each interface: It should be small and single responsible. Let's look at the List interface which is used in almost all Java based projects. Here are some main List methods.
Pretty clear and understandable, other programming languages have the same contract for lists.
However , the main idea of this post is.
Do you really need all those methods?
Let's look at an example from one of my pet projects J-Riddler
Class PrimaryKeys
implements List interface and delegate all List methods calls to the global variable primaryKeys
and here is an example how this class is used in test.
So what is the problem ? Well there many of them, first of all what if user will call add method and add new primary key to the list or what if user delete primary key(user means user of this class).
In order to prevent it java has some utility methods
which wrap List instance into immutable List
Collections.unmodifiableList(list);
.
Now when user tries to modify this list it throws an exception. However it is still a list.
Now users of this class have to remember that this list is immutable and doesn't support the
majority of it's methods. Does
it follow the Interface
segregation principle?
The answer in no , it doesn't. All classes that use PrimaryKeys
will depend on methods they
don't use. Could we
make it better by using interface without modification methods ? Well partly.
Java doesn't provide such interface. The closest one is Iterator , but it has
remove method which is not supported by default. Here is the list of Iterator
methods.
Few words before we start. There are a lot of java methods which accept Iterable instead of Iterator, so it would be better to implement Iterable interface which has a method that creates Iterator instance.
Now PrimaryKeys
class allows user to access
data without modifying the actual list of primary key names,
but what if we want to access element by index as in the
test above ? Well in this case it's up to the user to convert Iterable
into something else such
as Array.
Unfortunately, you can't create array using the syntax above( Maybe java will support custom constructors for array in the near future ,will see).
List is just a beginning
List is just an example. I face Interface segregation principle violation everyday when I work with backend services especially those which are Spring Based.
Let's say you have UserDao
(or Repository if you
use SpringData) interface with 10 methods which behave as a layer between service and
Database.
You inject this Dao into UserService
class and
you use only 3 methods out of 10.
Usually , as a result , this UserDao is injected into a lot of other classes but none of them use all methods.
Now lets say you need to operate with orders related to the User , in this case you inject OrderDao
into UserService and use only 2 methods
out of let's say
5.
Does UserService follow single responsibility principle now ? I don't think so. UserService has two Dao
instances but use both of them partly.
Conclusion
List is just an example how to spoil you architecture. Try to make your interfaces as small as possible. If users of your interface use only half of methods then probably you should redesign your interface and split it into smaller parts