Using patterns is a best practice, but please aim at doing it right.
Some of this advice is probably obvious, but it won’t hurt.
A shortened decalogue: yes, just nine commandments.
Preface: some of the caveats and warnings in using a pattern were not obvious in 1994, in the meantime we have learned more.
Do read the original, but keep in mind the modern context.
1) Do not Reinvent the wheel: no need to invent a pattern that is already listed among the traditional ones..
2) If you do need to invent a new pattern, document it, FULLY.
You should give the same sections that were in the original GoF:
Intent: the problem you want to solve
applicability: when it is appropriate to use the pattern
structure: normally a class diagram illustrating the class relationship
participants: who the subpart of your patterns are, e.g.: classes, structs and what their ROLE.
collaborations: a timing diagram if needed, a textual description of how the participants “talk” to each other.
consequences: benefits, possible bad consequences (caveats).
implementation: an example, commented implementation, in a real enough but not too complex case.
3) Don’t use a pattern if it adds more complexity instead of simplifying.
4) The purpose of a pattern is solving a problem, helping fellow humans reading your code.
5) A pattern is a solution applicable to a context. It is not a recipe, it is never applicable independently from the context.
5.1) Applying a traditional pattern to a problem that is outside its scope, you are probably making a mistake.
5.2) If you have invented a pattern, but you think it should be used always, you are okay only if you dictate how the OS interacts with all apps: e.g.:Apple.
6) Don’t use too many patterns.
7) The naming of patterns in code is an important matter (Old Deuteronomy is not a good name for a pattern, but it is a pretty name for a cat, gratuitous reference to T.S.Eliot and musicals)
Seriously,we should try to be more descriptive than just using a pattern and calling it by its pattern name, inside code.
We name things to be understood. We want to be easy on our fellow colleagues and help them.
e.g: the State Pattern, in the original GoF Book, the example was about the state of a TCP connection.
The GoF named it TCPConnection.
If your problem requires a Facade.
The definition you find in the GoF book is:
Intent: “Provide a unified interface to a set of interfaces in a subsystem.
Facade defines a higher-level interface and makes the system easier to use”
Unless that situation applies to you, you should not think about facade.
Facade is not an object that contains unrelated object references,
otherwise every composite class would be a facade. That would be a little overreaching.
The GoF clarifies that the purpose of facade is reducing the complexity
of the interface to multiple subcomponents
(by giving them a single interface).
E.g.: I having a single command interface to a compiler.
The compiler facade takes care of hiding the various compiler components it will call in stages:
preprocessor, parser, code generator, optimiser, assembler, linker.
It makes programmer’s life easier without hiding the lower-level functionality from the few that need it.
important note: so it should NOT remove the possibility of addressing the individual subcomponents.
if you use a pattern, What is that you want to achieve and why don’t you document and explain it? Please call it in a way that makes your intent obvious.
The example name for a good Facade example is Compiler, not “Facade to code generating steps”.
It is not (and it would have been even worse) ParserFacade, mentioning only the first subcomponent, the one you thought was the “core” of your problem.
For this name to make sense to the poor souls reading the code, they would need to realise that after parsing the facade drives other components, and the actual intent is generating an executable, eventually.
Applicability of a Facade is: reducing complexity, hiding the fact that subsystems may evolve, while their interface won’t, decoupling, layering subsystems. (read the book!)
Pattern naming within your code is a significant factor. Choose names that accurately reflect the pattern’s function, fostering clear understanding amongst your colleagues. For instance, the GoF named their State Pattern example ‘TCPConnection’, effectively conveying its function.
Patterns should be applied idiomatically, meaning language-specific features should be considered before applying traditional patterns. For example, a Swift developer should contemplate if an extension or protocol conformance is more suitable before resorting to an adapter. Misnaming language idioms as traditional patterns can lead to confusion and obscure the reasoning behind certain coding decisions.
Lastly, be cautious with some patterns like Singleton, which are prone to misuse. Using a pattern does not always equate to best practice.