$instance = new $className();It may be a failure of the programmer, or a failure of the language.
Established "Design Patterns" are hard or impossible to abstract away in a library, or they would not have become standard "Design Patterns".
Instead of looking at conceptual repetitions (of nice design concepts) as a good thing, we should look at them as a workaround for the languages' inability to abstract away these things in a library.
Many design patterns in C++ or Java are just simple closures or dynamically-typed results in Python:
* The Visitor pattern is the combination of multiple-dispatch and inversion of control pattern. Multiple dispatch is possible to generalize in a library for all cases or is a language feature in various languages.
* The inversion of control pattern is just a higher-order function in a language that supports these properly.
* The singleton pattern is just a lazily-initialized global variable, and can be abstracted by a library in some languages.
Design Patterns are in this sense, "language smell". It is a good measure of what kinds of useful things are hard or impossible to implement as libraries.
Consider: good code is less buggy, easier to debug when there is a problem, easier to maintain, easier to modify, easier to understand, etc. When devs work on good code it takes less effort and there are fewer problems so projects are done sooner. Good code is like a repellent for developer effort. Sometimes good code doesn't even need updating or maintenance, it just keeps working from version to version. In contrast, bad code is typically a time and effort sink. And because it's so difficult to work with, bad code typically doesn't improve in quality (merely in functionality) so it becomes more and more of an effort sink over time.
Time is money, developers spend more of their time mired in bad code, thus bad code is more expensive.
How about instead, you simply say what you're saying, without forcing the rest of us to do algebra on the language:
"Maintainable code is brief" pretty much summarizes that entire article. Note, however, that if you'd used that as the title we wouldn't have needed all those paragraphs of definitions.
Murphy's law: "What can go wrong WILL go wrong". So go over every line of code and ask: "How might this function do something unintended?". If you find any answer to that question then you need to change how the function works until the answer is: "This function physically cannot do something unintended". If the hardware and compiler are working to specification then the ONLY path through this code is the correct way through (or a pretty exception/error that tells you what the programmer/user did wrong or what the hardware/compiler failure was).
For example: you have a function calculate() which takes a collection of Strings which represents items to process. The problem is that function foo() might run incorrectly and some String items may become invalid or incorrect. Then calculate() will make its best attempt, then calculate may throw an exception/error or worst of all, it may work. The solution here is to make it physically impossible for the items in the list to become invalid/wrong, don't use an array of String, use an array of class Student/Airplane/Book/ProcessItem which has a constructor which validates its own existence as soon as it is made, it will produce a runtime error (or better yet a compile time error) the instant the programmer/user made a mistake.
The millions of unintended paths through calculate() which may throw a cryptic runtime exception has been eliminated. Imagine how much easier it is to diagnose a "InputProcessItemException" than a cryptic off-by-one error inside calculate();