Head First Design Patterns Series / 1 (Welcome to Design Patterns)

Building Extensible & Maintainable Object Oriented Software

Merve Arslan
Odeal-Tech
5 min readJan 12, 2023

--

In this series, you will accompany my notes as a summary from the book Design Patterns written by Eric Freeman & Elisabeth Robson and Kathy Sierra & Bert Bates.

Just before the first chapter, the authors gave us important notes about metacognition: thinking about thinking or activating the brain. I followed footsteps of the authors and started by taking notes about them first. Here are some of them :

  1. Slow down. The more you understand, the less you have to memorize.
  2. Do the exercises. Write your own notes.
  3. Make this the last thing you read before bed. Or at least the last challenging thing.
  4. Drink water. Lots of it.
  5. Talk about it. Out loud.
  6. Listen to your brain.
  7. Feel something.
  8. Design something.

Yes, if you’re ready let’s get it started 🤙🏻

The best way to use patterns is to load your brain with them and then recognize places in your designs and existing applications where you can apply them. Instead of code reuse, with patterns you get experience reuse.

The first chapter begins when Joe, a software developer working for a company developing a duck pond simulation game, is asked to add a new feature (fly & quack) to ducks. The initial designers of the system used standard OO techniques and created one Duck superclass from which all other duck types inherit. And Joe thinked “I just need to add a fly() method in the Duck class and then all the ducks will inherit it.”

What happened?

Joe failed to notice that not all subclasses of Duck should fly. When Joe added new behavior to the Duck superclass, he was also adding behavior that was not appropriate for some Duck subclasses.

A localized update to the code caused a nonlocal side effect !

Okay, what’s the one thing you can always count on in software development?

No matter where you work, what you’re building, or what language you are programming in, what’s the one true constant that will be with you always?

CHANGE

(use a mirror to see the answer)

No matter how well you design an application, over time an application must grow and change or it will die.

Take what varies and “encapsulate” it so it won’t affect the rest of your code.

Here’s another way to think about this principle: take the parts that vary and encapsulate them, so that later you can alter or extend the parts that vary without affecting those that don’t.

Separating what changes from what stays the same

Where do we start? As far as we can tell, other than the problems with fly() and quack(), the Duck class is working well and there are no other parts of it that appear to vary or change frequently. So, other than a few slight changes, we’re going to pretty much leave the Duck class alone.

Now, to separate the “parts that change from those that stay the same,” we are going to create two sets of classes (totally apart from Duck), one for fly and one for quack. Each set of classes will hold all the implementations of the respective behavior. For instance, we might have one class that implements quacking, another that implements squeaking, and another that implements silence.

We know that fly() and quack() are the parts of the Duck class that vary across ducks.

To separate these behaviors from the Duck class, we’ll pull both methods out of the Duck class and create a new set of classes to represent each behavior.

Then we will proceed with the second design principle:

So this time it won’t be the Duck classes that will implement the flying and quacking interfaces. Instead, we’ll make a set of classes whose entire reason for living is to represent a behavior (for example, “squeaking”), and it’s the behavior class, rather than the Duck class, that will implement the behavior interface.

Implementing the Duck Behaviors

HAS-A can be better than IS-A

The HAS-A relationship is an interesting one: each duck has a FlyBehavior and a QuackBehavior to which it delegates flying and quacking.

When you put two classes together like this you’re using composition. Instead of inheriting their behavior, the ducks get their behavior by being composed with the right behavior object.

This is an important technique; in fact, it is the basis of our third design principle:

Design patterns don’t go directly into your code, they first go into your BRAIN. Once you’ve loaded your brain with a good working knowledge of patterns, you can then start to apply them to your new designs, and rework your old code when you find it’s degrading into an inflexible mess.

For now, I end the first chapter of the series with this question that the authors leave the answer to our neurons.

Stay tuned for other chapters of the series.. ;)

--

--