A few weeks ago a customer needed two web services. One of them needed to return an image, the other some data in XML document form. The contract of these services didn’t really matter. And of course, haste was required. They had other companies who wanted to start their integration with these services.
It’s quite common that haste is required when adding value to software. Most of the time customers are in a hurry, meaning that they want to add the value as soon as possible.
This shouldn’t be thought of as annoying. In fact it can be rather helpful to know that haste is required. It means that there is something to focus on first.
You must never deal with haste by rushing into an implementation. Take the time to interact with your customer and end users. That allows you to do what’s necessary, and doing it right the first time.
We started on these web services with an attempt to define their contracts. These contracts are a great start for communication with the end users, the parties waiting to integrate with the services.
Then we left the web service contract part for what is was, and implemented the use cases. We didn’t bother to look at the web service view once. This put focus on the use cases, while we kept all options open for feedback on the contract.
After a few days the use cases were implemented. So we could continue with the view layer. In these few days we got the first feedback on the contract. We adjusted the contract and implemented the web services view on top of the use case implementations. We implemented these web services feedback-first.
Sure, I know the style we used to build the services is called contract-first. But defining a contract first, is all about communication and early feedback. It well-supports the lean principle “everybody, all together, from early on”. To emphasize this I like feedback-first in this post.
By the way, you should use contract-first development style for any service you build. I don’t elaborate on all the benefits here - use your Google skills to learn about this style.
Deferring the view
Now it’s easy to say that you should first define a web service contract, then leave it to generate feedback, and later on implement it on top of a web service agnostic application, after you got the feedback. But in order to do this, your architecture must allow you to defer the view. That means that your view must not be an integral part of the application, but instead, a plugin.
If you defer the view until you know how to build it, you can focus on getting the functionality done. And after you have sufficient feedback on the view, you implement it and plug it into the application.
In fact, deferring the view is only the technical consequence of deferring the implementation details for a particular stakeholder. And to be able to do that, you must make sure that the various stakeholders in your system are separated from each other. E.g. the use cases are driven by a different stakeholder than the web service view, so they must be decoupled.
So the architecture must partition the system so that different stakeholders are separated. Taking the image service as example here, on forehand I saw three stakeholders: our customer, who drives the use case, the parties integrating with the services, who drive the view, a virtual data stakeholder Hence they served the primary partitioning of the system. For the sake of this post, the virtual data stakeholder is left out - in the actual implementation it is decoupled by an image entity gateway.
The next picture gives you an idea of the partitioning.
The ImageWebService does all the translation of the web request into a vanilla data structure and passes it to the control object, Viewer. The Viewer performs all the use case interactions, and displays the image on the interface object, Display, which in fact is implemented by the ImageWebService (or some class close to it).
The partitioning allows to defer the implementation of the view and the data layer. It allows you to focus on use cases first, without bothering about the data or the view. Plus any part of the system whose implementation can be deferred, can also be changed or even replaced without affecting the rest of the system.
Uncle Bob did a Clean Coders episode on architecture; watch it if you haven’t. The architecture he talks about is much inspired by the work of Ivar Jacobson, which he wrote about in his book Object Oriented Software Engineering: A Use Case Driven Approach.