The first rule of design should be make it as simple as possible. And this book, I think, does the opposite for many people.
The first rule of design should be make it as simple as possible. And this book, I think, does the opposite for many people.
I think it is useful to say "This design could be thought of as a delegate" when explaining your code, but saying "We need a delegate design pattern here" is needlessly prescriptive.
> I think it is useful to say "This design could be thought of as a delegate" when explaining your code, but saying "We need a delegate design pattern here" is needlessly prescriptive.
1000% this. The authors of the book describe it as a catalog of existing solutions to be applied appropriately given specific criteria, not as a panacea to all engineering problems. I've worked with a few architectural prescriptivists who shoehorned everything into a GoF Design Pattern - and amusingly enough none of them had actually read it and so could only name the common ones like Repository, Factory, or Singleton. Everything that wasn't one of these was just a Facade as far as they were concerned. This definitely worked but it left much to be desired once you started venturing out of rote CRUD territory.
On the other hand I had one Team Lead that shunned such tradition and purposefully mashed several things I'd written (Facotries, Repositories, and a Service that encapsulated everything) into a single giant "Helper" class destroying any abstraction or separation of concerns in the process. I guess it made little difference because that team never wrote unit tests but it wasn't good design by any stretch.
I digress but the idea is thus: some things in our field are common and timeless. It's helpful to give them names and to understand what the historical pain points are. It's not helpful to use them as a whooping stick.
I've read "A Pattern Language: Towns, Buildings, Construction" which was the inspiration for the GoF book. That book had 253 patterns and they were written as "here are ways architects solve common problems". Pattern 148 - small work groups
> When more than half a dozen people work in the same place, it is essential that they not be forced to work in one huge undifferentiated space, but that instead, they can divide their workspace up, and so form smaller groups.
> In fact, people will feel oppressed, both when they are either working in an undifferentiated mass of workers and when they are forced to work in isolation. The small group achieves a nice balance between the one extreme in which there are so many people, that there is no opportunity for an intimate social structure to develop, and the other extreme in which there are so few, that the possibility of social groups does not occur at all.
> ...
> Break institutions into small, spatially identifiable work groups, with less than half a dozen people in each. Arrange these work groups so that each person is in at least partial view of the other members of his own group; and arrange several groups in such a way that they share a common entrance, food, office equipment, drinking fountains, bathrooms.
> Lay the workgroups out with respect to each other so that the distances between groups is within the constraints of OFFICE CONNECTIONS (82), and give each group office space which leaves room to expand and to contract-FLEXIBLE OFFICE SPACE (146); provide a common area, either for the group itself or for several groups together or both —- COMMON AREA AT THE HEART (129). Treat each small work group, in every kind of industry and office, as a place of learning—MASTER AND APPRENTICES (83). Give it its own stair, directly to the street—OPEN STAIRS (158). Arrange the individual workspaces within the small work group according to HALF-PRIVATE OFFICE 152) and WORKSPACE ENCLOSURE (183) . . . .
It's a not a dictate, but rather descriptive of "these are problems and ways people solved them" along with maintaining a unified vision of the design.
The GoF book became prescriptive instead. People used the patterns in anticipation of the problems rather than because they had them.
https://www.artima.com/articles/how-to-use-design-patterns
> Bill Venners: Is the value of patterns, then, that in the real world when I feel a particular kind of pain I'll be able to reach for a known solution?
> Erich Gamma: This is definitely the way I'd recommend that people use patterns. Do not start immediately throwing patterns into a design, but use them as you go and understand more of the problem. Because of this I really like to use patterns after the fact, refactoring to patterns. One comment I saw in a news group just after patterns started to become more popular was someone claiming that in a particular program they tried to use all 23 GoF patterns. They said they had failed, because they were only able to use 20. They hoped the client would call them again to come back again so maybe they could squeeze in the other 3.
> Trying to use all the patterns is a bad thing, because you will end up with synthetic designs—speculative designs that have flexibility that no one needs. These days software is too complex. We can't afford to speculate what else it should do. We need to really focus on what it needs. That's why I like refactoring to patterns. People should learn that when they have a particular kind of problem or code smell, as people call it these days, they can go to their patterns toolbox to find a solution.
---
The Patterns from GoF became the goal without understanding what a Pattern is. It's a way to hold complexity. A function call is a Pattern. Store volatile registers onto stack, put return address onto stack, put parameters onto stack, jump to new instruction, restore registers.
That Pattern is now hidden inside of `foo(bar, qux)` and that hides a lot of the complexity for what is being done.
But we don't come with the idea that to write a good program, you must use functions. Well, you should because they're likely complex enough to need them... but we use them when we need to manage that complexity.
A phrase I used before was that the GoF isn't a cookbook but rather a bestiary of complexity.
The problem is when people use Patterns in anticipation of complexity that isn't there. So when they're putting patterns in places, as a maintainer you see dark and (maybe) empty cages. Do you want to stick your hand in it to see if it will get bitten off?
Don't have empty complexity cages. And when you do need the complexity cage, properly illuminate it with a clear description of what it is and what complexity it contains.
(yes, I can rant about Patterns)
https://c2.com/ppr/wiki/WikiPagesAboutWhatArePatterns/Patter...
And one of the blog posts of yesteryear that influenced me - https://perl.plover.com/yak/design/
Being able to say "circuit breaker" pattern or "visitor" is a time efficient way to communicate complicated ideas. Its value is being able to conserve the limited bandwidth speaking has.
Bad coders will always find something or another to justify their work with and it just so happens the most popular book is often referenced, for good and bad.
It's been so successful that the only thing left to do is talk about scenarios in which it doesn't work.
Reminiscent of the Dark Knight quote -
"You either die a hero, or you live long enough to see yourself become the villain."
The problem is, people treat it like a "here's how to do OO design" book. It is not suited to that, and especially not suited to being the one and only OO design book that people read.
But a gadget-centric process, whether is patterns or microservices, constrains the design space to assemblies. and that a really small and clunky part of the space.
It goes in cycles, once the contrarian position becomes established, reverting to the original becomes the new cool. The "it's good actually", or that meme where the dumb guy thinks simple thing X, the mediocre average guy thinks a loooong, elaborate sophisticated thing Y, and the wise guru thinks simple thing X again.
GoF was long enough ago that if you're advocating for it, it seems dated, it seems you're either a novice or someone who came of age at that time and has not read anything new since. It's like someone suddenly discovering Kahneman and cognitive biases and argumentation fallacies and proselytizing on them. Regardless of the merits, culture has moved on, has digested it, built in the good parts, spat out the bad, and the zeitgeist is elsewhere.
Most design patterns were invented as workarounds to specifics and limitations of certain languages/paradigms, and work great in that case -- but are much more limited, or even downright dangerous, when used in other contexts. As a clear example, the GoF patterns focus on strongly typed OOP languages like Java or C++, and will result in difficult to maintain bloatware if copied directly to dynamic languages like Python, Javascript or PHP (source: been there, done that, got the t-shirt).