I see some wrong assumptions in this question:
- code with design patterns, though applied correctly, needs more time to be implemented than code without those patterns.
Design patterns are no end in itself, they should serve you, not vice versa. If a design pattern does not make the code easier to implement, or at least better evolvable (that means: easier to be adapted to changing requirements), then the pattern misses its purpose. Don't apply patterns when they don't make "life" easier for the team. If the new Null object pattern was serving your friend for the time he used it, then everything was fine. If it was to be eliminated later, then this could be also ok. If the Null object pattern slowed the (correct) implementation down, then its usage was wrong. Note, from this part of the story one cannot conclude any cause of "spaghetti code" so far.
- the customer is to blame because he has no technical background and does not care about cohesion or the coherence of the product
That is neither his job nor his fault! Your job is to care about cohesion and coherence. When the requirements change twice a day, your solution should not be to sacrifice the code quality. Just tell the customer how long it takes, and if you think you need more time for getting the design "right", then add a big enough safety margin to any estimation. Especially when you have a customer trying to pressure you, use the "Scotty Principle". And when arguing with a non-technical customer about the effort, avoid terms like "refactoring", "unit-tests", "design patterns" or "code documentation" - that are things he does not understand and probably regards to be "unnecessary nonsense" because he sees no value in it. Always talk about things which are visible or at least understandable to the customer (features, sub-features, behaviour changes, user docs, error fixes, performance optimization, and so on).
- the solution for rapid changing requirements is to rapidly change the code
Honestly, if "underlying interfaces change twice per day for three months", then the solution should not be to react by changing the code twice a day. The real solution is to ask why the requirements change so often and if it is possible to make a change at that part of the process. Maybe some more upfront-analysis will help. Maybe the interface is too broad because the boundary between components is chosen wrong. Sometimes it helps to ask for more information regarding which part of the requirements are stable, and which are still under discussion (and actually postpone the implementation for things under discussion). And sometimes some people just have to be "kicked in their asses" for not changing their minds twice a day.
These are the words of someone who has found success and ignores people that try to tell him what to do in pattern jargon that he doesn't understand.
Design patterns and best practices are not the same thing. Some people think they are and drive people who know what they're doing nuts. Even if they don't know the proper name for what they are doing.
Design patterns existed before they had names. We gave them names to make talking about them easier. A pattern having a name doesn't make it a good thing. It makes it a recognizable thing.
This guy is likely using patterns neither one of you ever heard of. That's fine, until you need to talk to him about how something is done. He's either going to have to learn how to talk to you or you're going to have to learn how to talk to him. Has nothing to do with who is "right."
Best Answer
For my money, I think everyone's missing the point of design patterns. It's rare that I sit wondering which pattern I should use in a given situation. Also, I was using most of those patterns long before I knew they had names.
The power of design patterns is in communication. It is much quicker for me to say "use a Strategy for that" than to describe in detail what I am suggesting. It is much easier for us to debate the benefits of fat domain models vs. transaction scripts if we all know what those two terms mean. And so on.
And most powerfully of all, if I have named a class FooBuilder then you know that I'm using the Builder pattern to generate my Foo.
Even if you don't know what I'm talking about when I say "Observer pattern is ideal for that," you will be able to go off and google it pretty easily.
In that sense, the power of design patterns will never fade.