I couldn't agree more. I have seen so many examples of efforts of trying (too hard) to "design something for reuse since reuse will save us so much time and money". Designing something to accommodate for future business requirements is extremely difficult since these requirements tend to be changing rapidly. You almost never know in advance the exact requirements of future uses of your code.
There are several problems with designing for reuse:
- Trying to design for generality in advance typically leads to overdesigning in a very non-XP way. This in itself might increase the costs of developing the general solution which can then be reused.
- There are always little twists which make two seemingly similar usecases different. These little differences tend to make the general design jump through loops in order to cater for the differences. It typically makes the general code less easy to read and maintain due to the handling of the differences and it definitely adds to the costs.
- Even when to usecases are similar when developed, I have seen many examples of business requirements "drifting apart", requiring the general code to adapt to the new gap between the usecases. Adapting to changes in one usecase may prove to be difficult as the changes apply to the general code. You need to be really careful with changes to the general code as it affects all the implemented usecases. And we're not even talking by the extra efforts in testing, since all the implemented usecases must be re-tested.
This is not an excuse for not creating quality design. I'm not saying that you should just copy-and-paste your way through the application - the DRY principle (Don't Repeat Yourself) still holds. However, I think it is important to really think carefully of whether reuse is feasible and find the right spots to reuse.