A commenter (Daniel) on my previous post had this to say [summarized from multiple comments]:
if you assume that requirements can be well defined and are static for the lifetime of the product, then programming is trivial. I’ve never seen this assumption to be true. [...]
at the level of programming, what do you have to do to minimise the amount of code that is affected by arbitrary requirements changes? [...]
If you learn one thing from the first project that you do, it is that users are fickle. They change their minds. They tell you one thing and the exact opposite sometime later. They will be adamant in stating that something is required (or unnecessary) and then contradicting themselves (sheepishly or shamelessly). Often they don’t understand the consequences, such as additional effort and money required, even if they are the ones who are on the hook for the cost. This is not unique to software projects. Construction projects are another example.
There are many responses to changing requirements or “scope creep”, as it is commonly called. One is switching the billing model from “fixed cost” to “time and material” which puts the onus on the customer to control scope and get it done faster. It also switches risk to the customer because if you are a bad/unethical programmer, they could be paying more for their project to materialize. There are a variety of other billing models that try to share the risk between the customer and the developer by incorporating incentives and fines.
But let’s suppose the model is “fixed cost”. You can give an accurate cost when you know exactly what you are going to build. But in real life, many things prevent you from determining exact requirements before providing an estimate. One is that you have to provide an estimate before a particular deadline, which precludes you from doing extensive analysis. Another is that the analysis for an estimate is done on your dime, and there are limits to how much free consulting you want to give a customer. A way around this to split the project into an analysis stage (paid by the customer) pending an estimate for the actual work. But some customers may not go for that.
Therefore, you tend to walk away from projects that you are unsure about. You take on projects that you can relate to your existing knowledge or past experience. Write out a reasonable specification that outlines the boundaries of what you will do and what you will not. Plan for contingencies. Allocate a buffer.
So far, so good. The customer accepts your bid and you start work. But then as the project starts to come into shape, the customer starts getting ideas. You can reject some as they are clearly outside the scope of work. But others fall into the “difference of opinion” area. You think they are not in the scope, the customer disagrees. You have 2 choices. You can stick to your guns, risk offending the customer and deliver what you promised. You are well within your rights to do that, but you run the risk that if you offend the customer too much, maybe you won’t work with them again (which may or may not be a good thing!). The other possibility is to accept the customer’s request. Maybe it is something you can easily do. Why displease the customer when it takes a few extra minutes? The customer grins and you bear it.
There is nothing wrong with either approach (within limits). As a business that needs to stay in business, you have to be profitable. As a business that needs to grow, you have to keep existing customers. Usually, you mix it a bit. Saying no to some things and accommodating others. Be reasonable, but don’t let the customer run over you. Pay attention to the bottom line.
All this is to simply state: There are business strategies that can be used to manage scope creep while keeping both customer and vendor benefit and risk in balance. Handling this is the role of the person(s) playing the project manager role in the team. If the project is done by a single programmer, they have to make these business decisions.
Unfortunately, with software, we see a tendency for some programmers to blame themselves if they cannot accommodate the customer’s every request. They see that as a failure of the code that they have written. Fundamentally, this is an extremely short-sighted and destructive view. It moves every responsibility and risk from the customer’s shoulders to the software vendor and development team as there is no incentive for the customer to control scope and the resulting costs.
Know this: Writing software costs money. It costs the customer money directly. When there is scope creep, it costs the customer more money, or it costs the vendor money for paying the programmers. And there are opportunity costs for not being able to do other paid work because of unexpected changes. Even the simplest arbitrary requirement change costs someone money, whether it is written off as a business expense or not.
But let us give the benefit of doubt to our software programmers and assume a world where gold-plating does not cost any money. Let us ignore the additional effort spent to create software that can minimize code changes. Let us even assume that there is a mandate from the customer to create a software that can accommodate any whim that they have.
Well, what could that be? Maybe the customer wants to add, and remove fields whenever they want? Maybe they want to change the relationships between different entities? Or they like to modify the business rules and actions that happen in the system? Or they want to modify the user interface? They like pulling odd reports just for the fun of it?
Your road to nirvana is to understand the truth: What your fickle customer wants is a glorified compiler.
But no customer will tell you that, even if they knew it to be so. And you will be in this amazing world of layering, low coupling, single responsibility, inversion of control, interfaces, contracts, messaging, user-friendly configuration files, functional programming, etc. to try to emulate Eclipse, Microsoft Access, Crystal Reports, and whatever mass-market products the customer has laid eyes upon. And that is when it seems so challenging: 5 months to deliver “Visual Studio” to the customer.
P.S. What about the case of software with hundreds of customers? Shouldn’t the software be more flexible? I think the answer is the one given by 37Signals: keep it simple. But I will elaborate upon it in my next post.