A friend of mine is working for a small company on a project every developer would hate: he's pressured to release as quickly as possible, he's the only one who seem to care about technical debt, the customer has no technical background, etc.
He told me a story which made me think about the appropriateness of design patterns in projects like this one. Here's the story.
We had to display products at different places on the website. For example, content managers could view the products, but also the end users or the partners through the API.
Sometimes, information was missing from the products: for example, a bunch of them didn't have any price when the product was just created, but the price wasn't specified yet. Some didn't have a description (the description being a complex object with modification histories, localized content, etc.). Some were lacking shipment information.
Inspired by my recent readings about design patterns, I thought this was an excellent opportunity to use the magical Null Object pattern. So I did it, and everything was smooth and clean. One just had to call
product.Price.ToString("c")to display the price, or
product.Description.Currentto show the description; no conditional stuff required. Until, one day, the stakeholder asked to display it differently in the API, by having a
nullin JSON. And also differently for content managers by showing "Price unspecified [Change]". And I had to murder my beloved Null Object pattern, because there was no need for it any longer.
In the same way, I had to remove a few abstract factories and a few builders, I ended up replacing my beautiful Facade pattern by direct and ugly calls, because the underlying interfaces changed twice per day for three months, and even the Singleton left me when the requirements told that the concerned object had to be different depending on the context.
More than three weeks of work consisted of adding design patterns, then tearing them apart one month later, and my code finally became spaghetti enough to be impossible to maintain by anyone, including myself. Wouldn't it be better to never use those patterns in the first place?
Indeed, I had to work myself on those types of projects where the requirements are changing constantly, and are dictated by persons who don't really have in mind the cohesion or the coherence of the product. In this context, it doesn't matter how agile you are, you'll come with an elegant solution to a problem, and when you finally implement it, you learn that the requirements changed so drastically, that your elegant solution doesn't fit any longer.
What would be the solution in this case?
Not using any design patterns, stop thinking, and write code directly?
It would be interesting to do an experience where a team is writing code directly, while another one is thinking twice before typing, taking the risk of having to throw away the original design a few days later: who knows, maybe both teams would have the same technical debt. In the absence of such data, I would only assert that it doesn't feel right to type code without prior thinking when working on a 20 man-month project.
Keep the design pattern which doesn't make sense any longer, and try to add more patterns for the newly created situation?
This doesn't seem right neither. Patterns are used to simplify the understanding of the code; put too much patterns, and the code will become a mess.
Start thinking of a new design which encompasses the new requirements, then slowly refactor the old design into the new one?
As a theoretician and the one who favors Agile, I'm totally into it. In practice, when you know that you'll have to get back to the whiteboard every week and redo the large part of the previous design and that the customer just doesn't have enough funds to pay you for that, nor enough time to wait, this probably won't work.
So, any suggestions?