Design Patterns

May 30, 2024

The cover of 'Design Patterns' by the 'gang of four'

All Hail The Object

Design Patterns is a classic book from the 90s that centers around low-level OOP idioms. While I’m sometimes quick to criticize OOP1, I still think there’s a lot of utility in understanding its principles and learning to work with it.

This is partially because OOP is so widely used: even in languages that claim to be multi-paradigm (e.g. Python and Rust), objects play a huge role in code organization. In order to work with these languages at max-capacity, it’s critical to work with the standard idioms, not to fight against them.

But perhaps more importantly, I think there’s something inherently effective about OOP: its widespread adoption cannot solely be a fluke. While there are certainly flaws in thinking in terms of “everything as an object”, and the mechanics around that, there are many advantages too, which allow for increased code efficiency and productivity. My goal is to find those advantages across every paradigm, OOP included.

I’ve spent the past few days reading the book, and I’ve synthesized the key details (and some of my thoughts surrounding them) into this post.


Here are some compelling quotes from the introduction of the book: I think they do a nice job motivating the use of design patterns (and also reservations).

“The hard part about object-oriented design is decomposing a system into objects.The task is difficult because many factors come into play: encapsulation, granularity,dependency, flexibility, performance, evolution, reusability, and on and on. They all influence the decomposition, often in conflicting ways” (11).

“That leads us to our second principle of object-oriented design: Favor object composition over class inheritance” (20).

“Design patterns should not be applied indiscriminately Often they achieve flexibility and variability by introducing additional levels of indirection, and that can complicatea design and/or cost you some performance. A design pattern should only be applied when the flexibility it affords is actually needed” (31).

The last two quotes highlight the important idea that these patterns must be used in moderation. The authors hold this sentiment throughout the book, and it voids the vast majority of the criticisms I expected to have. I’m glad that this didn’t turn out to be a manifseto for Enterprise FizzBuzz. Anybody who thinks that probably hasn’t actually read it.

Creational Patterns

Structural Patterns

Behavioral Patterns

  1. Usually in favor of FP… ↩︎

  2. The methods effectively provide documentation, because they label each of the fields (as opposed to having a lengthy constructor call with unlabeled arguments). ↩︎

  3. I’d be willing to bet that most of us have written more react apps than interpreters. ↩︎

  4. Iterators need not be lazy or infinite to apply these operations, but it’s often a useful option. ↩︎

  5. This could also be viewed as an instance of the observer pattern, where there is only a single observer, and it is notified via calling a single function pointer. The book/OOP-POV also implies that the template method is used in the context of inheritance/subtyping. ↩︎

  6. The methods of the “visitor” class rely on manual naming and remembering to call the right method, and not forgetting to recurse. ADTs force destructuring, and directly use the type name, so it’s harder to mess up with them on that front. ↩︎