Designing Flexibility (Against Client's Wishes)Source: comp.object
Problem: Should we create a flexible design even if the client insists that the flexibility is unnecessary?
This problem arose in a discussion of the good old ATM (Caspomat) design. The client requires that the user insert a VISA to the ATM and enter a PIN number. An obvious abstraction is to state that the user authenticates herself to the ATM.
Robert C. Martin started this discussion when he wrote:
That is one of the reasons that I consider this step [abstraction -YS] to be part of design. You see, I don't trust the user. I know that the user is going to want to see the word 'VISA' in the analysis. I know that if I attempt to abstract that out then there is a high likelihood that the user will ask: "But where's the VISA card, I want to see the VISA card.".
I might try to explain to the user that I am trying to set things up so that any form of identification can be used. But my experience tells me that the user (and probably several managers along the way) will equate this with "more work" and "more cost", and will put pressure on me to abandon my silly over-engineering and stick to the problem at hand.
However, I know damned well that before we are finished producing this project, that same user is going to come back and want to use MasterCard. And later he will want Debit cards. And still later he will want to use smart-cards. And a couple of years from now he might even want to use drivers licenses, or thumbprints.
When these request are made, if tell the user that those changes will be very difficult because we based the design on VISA, he is going to be very upset, and will accuse me of improperly engineering the application.
And so, I design the flexibility into the application. I make sure that the structure of the application, the very code itself, can withstand the changes that I anticipate the user will be sending to me.
Michael Malak noted:
Interesting. Your solution is to design the flexibility and not tell the customer?
It seems to me there ought to be a way to present it in terms of risks, probabilities, and costs, with historical data to back up claims.
I'm considering using the ideas presented in Investment Analysis of Software Assets for Product Lines.
But risk and investment is an emotional issue. Obviously risk "values" vary from one person to another. But they can vary even for a single person from one time to another. Even if one could quantify the risks, how could one communicate them to the other stakeholders (users, managers, other developers) while minimizing the variability due to emotion?
Robert C. Martin then replied:
I will inform the customer that the design will be flexible. I also try to asses the customer's need for that flexibility. In the end, however, I choose whether the flexibility goes in; not the customer. I base this on what I perceive the customer's need to be.
I view this as basic engineering integrity. I will not allow the customer to shoot himself in the foot. I - being the engineer - have a responsibility to provide a solution for the customer.
Consider a doctor who refuses to give pain medication to a patient because the doctor knows that that medication is addictive. The patient is in pain, but will recover. The patient demands the painkiller, and the doctor refuses because the medication will do more harm than good.
I consider this to be equivalent to the customer who demands that all flexibility be removed from the software in order to shorten the development time; when that shortening is not really critical.
So, do I tell them about the flexibilities that I build in? Not in particular. But they know my position. When they ask me if there is any way to do this faster; I do not tell them that we could do it faster by hacking. I don't consider that an option.
As a result, one of my customers recently told his boss: "With all the changes we have been making to the spec over the last 4 years, the design has not unraveled. These guys have really delivered."
Nick Thurn commented:
The line between "over-engineering" and "flexibility" is a difficult one to tread. To be able to make the judgments required you have to look at the problem domain closely and understand it, be technically competent enough to produce a clean flexible design rather than a mess and last you have to consider the realities of the actual project (you may have a dropdead delivery, eg the 2000 Olympics).
IME inventing flexibility is not a good idea. Unless it's really needed it just sits there unused making the system more complex and hence less maintainable. The worst case is where it is actually wrong, eg a POS system for a hardware store does not usually need to be multi-currency.
My point is you can't just design flexibility, you have to discover where it's really of value.
Brandon Goldfedder, BuildForTodayDesignForTomorrow.