Prematurely introducing complexity by implementing design patterns before they are needed is not good practice.
But if you follow all (or even most of) the SOLID principles and use common design patterns you will introduce some complexity as features and requirements are added or changed to keep your design as maintainable and flexible as needed.
However once that complexity is introduced and working like a champ when do you removed it?
Example. I have an application written for a client. When originally created there where several ways to give raises to employees. I used the strategy pattern and factory to keep the whole process nice and clean. Over time certain raise methods where added or removed by the application owner.
Time passes and new owner takes over. This new owner is hard nosed, keeps everything simple and only has one single way to give a raise.
The complexity needed by the strategy pattern is no longer needed. If I where to code this from the requirements as they are now I would not introduce this extra complexity (but make sure I could introduce it with little or no work should the need arise).
So do I remove the strategy implementation now? I don't think this new owner will ever change how raises are given. But the application itself has demonstrated that this could happen.
Of course this is just one example in an application where a new owner takes over and has simplified many processes. I could remove dozens of classes, interfaces and factories and make the whole application much more simple. Note that the current implementation does works just fine and the owner is happy with it (and surprised and even happier that I was able to implement her changes so quickly because of the discussed complexity).
I admit that a small part of this doubt is because it is highly likely the new owner isn't going to use me any longer. I don't really care that somebody else will take this over since it has not been a big income generator.
But I do care about 2 (related) things
I care a bit that the new maintainer will have to think a bit harder when trying to understand the code. Complexity is complexity and I don't want to anger the psycho maniac coming after me.
But even more I worry about a competitor seeing this complexity and thinking I just implement design patterns to pad my hours on jobs. Then spreading this rumor to hurt my other business. (I have heard this mentioned.)
In general should previously needed complexity be removed even though it works and there has been a historically demonstrated need for the complexity but you have no indication that it will be needed in the future?
Even if the question above is generally answered "no" is it wise to remove this "un-needed" complexity if handing off the project to a competitor (or stranger)?