As elaborated in an earlier post, ‘Design for Change’ is one of the main architectural principles in Agile. So, while the ‘why‘ is explained earlier, one of the how’s (proper interfaces) is explained in this one.
Interface definition is not about technology
The proper interface definition practices are about as old as programming. Still, wrongly defined interfaces are one of the common and major impediments in delivering a system designed for change.
An important misunderstanding about interfaces between components or systems is that it is all about technology and techies should take care of it. But, how much does it really cost to implement or refactor e.g. from SOAP to REST; or from JMS to HTTP? Practically nothing when compared to functionally highly coupled components because of badly defined interface regardless of technology.
Never make generic interfaces
One of the worst practices in this area are so called SOAP gateways or ESB’s, which only make technical stuff more complex and when connecting two systems, still requiring from involved parties to define functionally working interface. This real interface is not explicit anymore, often described in some large document, and hidden deep in involved systems.
So, what is the problem? Well, most of the changes in service providing systems have huge costs because of the impact on consuming systems / components and middleware.
One of the bizar things architects tend to say is that things like SOAP gateways or ESB’s decouple systems, because you can place anything in the request and response placeholders. It’s like: let’s forget about language so we can say to each other anything we want.
Making functionally explicit, fit for context and purpose, simple, and specific interfaces between components, understandable by product owner and sometimes even users gives you a lot of space to move and change. It also makes all real dependencies explicit and easy to use.
For example:
- one generic: update(bookReservation);
- multiple specific methods: reserveBook(bookId,customerId); cancelReservation(bookId); bookReturned(bookId); and so on.
Also, if consuming components only need few details of a book reservation; do not send the whole source object, but create a separate DTO (Data Transfer Object) containing only these fields. It is always easier to extend this later if more is needed, than to change existing field.
Agile or not, changing an interface functionally is expensive. Think about complexity of having multiple versions and so on. Single most imporant factor to reduce this costs is to make very explicit interfaces. It means that your interface only describes the strictly necessary information for the purpose and nothing more. This all does not mean that you always define fine-grained interfaces. In contrary, you don’t want separate methods for each field of an object, but rather to have one BookReservationDTO used by as many as possible service consumers. Defining such objects is a balancing act mainly influenced by specific domain and how realistic it is to have one object for all consumers. Because we do stuff in an Agile manner, we can safely name our object BookReservationDTO containing only the bare minimum of fields.
Well-defined interface is a powerful wedge for changes
There is another reason why we appreciate good interfaces so much. It makes a whole new range of creative solutions possible.
I learned this example from Michael Franken (Zilverline): Imagine wanting CRM solution really fast, but don’t know all needed features yet and buying complete solution so early is also very expensive. In other words, unwanted big bang with all disadvantages. But you also don’t want to build it yourself.
You could build only user interaction stuff with simplest possible technology while backend is just a database or some in memory solution. No interfaces to others systems and complex business rules and logic. You do make sure from start that interfaces from user interface to the repository with data are very well defined. Later on, you can (gradually) replace this backend database solution with fully featured out-of-box CRM solution. You can also use these interfaces as perfect specs for buying such system.
Conclusion
Also Agile teams need to be very careful when defining interfaces. But, it’s all about functionally well thought-out interfaces and not about SOAP, REST and so on. These are simply not important, because they are cheap to change or add. Agile says: “Do The Simplest Thing That Could Possibly Work”.
One thought on “Functionally well-defined interfaces crucial for ‘Design for Change’!”