It's not about methodologies, but about communication with a customer.
I had many situations where customers wanted to constantly add new features to a non-finished project, and were surprised why it would increase the overall cost and delays. The context and the personality of those customers being different, it required different approaches, but I may try to isolate some guidelines and advice:
- Ensure that a customer has an access to the general information required to understand why a change in a requirement may impact both cost and delay. In other words, publish some articles about those things, explaining what a non-technical person may not know at all.
For example, for most people, it's totally weird that a change they consider tiny may have a huge impact on the project and be very expensive (see example in my question). If they ask to do some changes, and every time you tell them, without explaining anything, that they would have to pay thousands of dollars when they expected it for free or for a few dozens of dollars, they would probably think you're just stealing their money. This is especially true since some unethical programmers and software companies develop unmaintainable products (so you can't ask to change it later by a normal developer), then ask you to pay too much for every modification.
- Ensure that a customer has understood why the specific change she wants has an impact on a cost. For that, you can give her the links to your articles (see the previous point), or just summarize, in a non-technical way, what is required in order to make a requested change.
Such explanations are also a good idea since they enable your customer to have a better understanding of the product and the change. In a few cases, some of my customers ended by saying that the change they wanted was not too smart, and that they will do it in other way. You can also suggest things. It is highly appreciated by some customers (warning: some other hate it), and shows that you know what are you talking about (by comparison to the code monkey who just translates the requirements into code, without thinking too much about the possible approaches).
- Ensure that a customer cannot do whatever she want, unless she's really sure. For some people, the only way is to lock the requirements definitively before starting to code. Otherwise, it is a disaster, and the project will never end. For others, it's just a good idea to never see an unterminated project (in general my customers have live access to the unterminated product very early, so they can make comments/adjustments early too).
For example, I had a customer who, after sending "final" requirements, sent, on average, ten mails per day with ten requirement changes, going from minor modifications ("Can you change the border width of the middle zone on the home page from three to six pixels ?") to the changes which affected the whole project (after two months of development, one week before the release : "Finally, I think ASP.NET is a bad idea. Could you switch to PHP please?").
So for that customer, we were forced to lock all requirements before writing code. It was written in the contract. No changes were accepted before the final release.
It wasn't too bad, finally, since curiously it us allowed to be very organized: the project was released, according to the old requirements, and then, a few days later, we started the next version from scratch with a completely different set of requirements.