Design Patterns: Elements of Reusable Object-Oriented Software

Author: Ralph Johnson, Erich Gamma, John Vlissides, Richard Helm
All Stack Overflow 198
This Year Hacker News 4
This Month Stack Overflow 2

About This Book

Capturing a wealth of experience about the design of object-oriented software, four top-notch designers present a catalog of simple and succinct solutions to commonly occurring design problems. Previously undocumented, these 23 patterns allow designers to create more flexible, elegant, and ultimately reusable designs without having to rediscover the design solutions themselves.

The authors begin by describing what patterns are and how they can help you design object-oriented software. They then go on to systematically name, explain, evaluate, and catalog recurring designs in object-oriented systems. With Design Patterns as your guide, you will learn how these important patterns fit into the software development process, and how you can leverage them to solve your own design problems most efficiently.

Each pattern describes the circumstances in which it is applicable, when it can be applied in view of other design constraints, and the consequences and trade-offs of using the pattern within a larger design. All patterns are compiled from real systems and are based on real-world examples. Each pattern also includes code that demonstrates how it may be implemented in object-oriented programming languages like C++ or Smalltalk.


by anonymous   2017-11-27
Re, "Is there some design pattern involved in...?" It _is_ a design pattern. A design pattern is any way of doing something that is replicated by lots of developers. The purpose of the original [Design Patterns book]( was to teach us to give them names so that we may more easily talk about them. I don't know if there's a better name, but most developers would know what I was talking about if I said, "...create a thread with a `Runnable` _delegate_."
by gnufied   2017-08-20
What i listed was just an example but you can verify quickly - without opening the actual book.

And afaict - none of the patterns I listed are mentioned verbatim.

by PaulKeeble   2017-08-20
The classical Design Patterns book has a first chapter which takes you through the design of a text editor using the patterns provided in the book. If what you do is read the chapter and then the patterns referenced as you go and build the text editor based on their design you get exactly the sort of thing you are looking for. Its a different way of doing it than the entire book but arguably just in a different format for what is otherwise a reference book.

by anonymous   2017-08-20

No, that does not violate any OOP principle.

A prominent example is an object who's behavior depends on whether a connection is established or not (e.g. function doNetworkStuff() depends on openConnection()).

In Java, there is even a typestate checker, which performs such checks (whether Duck can already Quack()) at compile time. I often have such dependencies as preconditions for interfaces, and use a forwarding class whose sole purpose is protocolling and checking the state of the object it forwards to, i.e. protocol which functions have been called on the object, and throw exceptions (e.g. InvalidStateException) when the preconditions are not met.

A design pattern that handles this is state: It allows an object to alter its behavior when its internal state changes. The object will appear to change its class. The design pattern book from the Gang of Four also uses the example above of a network connection either being established or not.

by anonymous   2017-08-20

You have to make up your mind whether the so called apple-specific method (in this case checkPrice()) is really specific to Apple. Or it is actually generally applicable to all fruits.

A method that is generally applicable should be declared in the base class

Assuming the answer is yes (in this case it does seems to be yes), then you should declare the method in the base class. In this case you can iterate through all the different types of fruits, and all of them would accept the method checkPrice(), so you don't even need to make a special case for apples.

A method that isn't generally applicable can be declared in an interface

What if the answer is no? Let's assume we need another method called getJuicePrice(), and we further assume that only some fruits can be made into juice (apple juice, orange juice) but other cannot (pineapple? durian?). In this case, a simple solution is to declare an interface, and only the fruits for which the method is appropriate would implement the interface. So let's say this interface is JuiceBehavior

package fruitcart;

import java.math.BigDecimal;

public interface JuiceBehavior {
    BigDecimal getJuicePrice();

And all fruits for which juice behavior is applicable (yes for Apple, no for Durian) would implement the interface:

package fruitcart;

import java.math.BigDecimal;

public class Apple implements JuiceBehavior {

    public BigDecimal getJuicePrice() {
        // FIXME implement this
        return null;


And then in your loop, what you check is whether a fruit is instanceof the interface:

if (fruit instanceof JuiceBehavior) {
    System.out.format("can be made into juice "
        + "with price $ %.2f%n", fruit.getJuicePrice());
} else {
    System.out.format("cannot be made into juice %n");


This solution would work for simple cases, but in more complicated cases, you may notice that you start to duplicate a lot of implementation code for getJuicePrice() for different types of fruits. This leads to the next topic

Design Pattern: Strategy

You may want to start thinking about the Design Pattern called Strategy, which further encapsulates JuiceBehavior and make it into a family of classes representing different juice behaviors. It also let you set different types of fruits to take different implementations of JuiceBehavior. I won't go into the details here. But you can read up on that on some books about Design Patterns. Such as

  1. Design Patterns: Elements of Reusable Object-Oriented Software
  2. Head First Design Patterns: A Brain-Friendly Guide
by Bill the Lizard   2017-08-20

Head First Design Patterns

alt text

and the Design Pattern Wikipedia page are the best resources for beginners. FluffyCat is another good, free online resource for design patterns in both Java and PHP.

The Gang of Four book is where to go afterward, but it's fairly advanced, so I'd wait until you have a pretty firm grasp from the other resources.

by anonymous   2017-08-20

Can somebody please explain in layman's terms?

Design patterns are not really "layman" concepts, but I'll try to make it as clear as possible. Any design pattern can be considered in three dimensions:

  1. The problem the pattern solves;
  2. The static structure of the pattern (class diagram);
  3. The dynamics of the pattern (sequence diagrams).

Let's compare State and Strategy.

Problem the pattern solves

State is used in one of two cases [GoF book p. 306]:

  • An object's behavior depends on its state, and it must change its behavior at run-time depending on that state.
  • Operations have large, multipart conditional statements that depend on the object's state. This state is usually represented by one or more enumerated constants. Often, several operations will contain this same conditional structure. The State pattern puts each branch of the conditional in a separate class. This lets you treat the object's state as an object in its own right that can vary independently from other objects.

If you want to make sure you indeed have the problem the State pattern solves, you should be able to model the states of the object using a finite state machine. You can find an applied example here.

Each state transition is a method in the State interface. This implies that for a design, you have to be pretty certain about state transitions before you apply this pattern. Otherwise, if you add or remove transitions, it will require changing the interface and all the classes that implement it.

I personally haven't found this pattern that useful. You can always implement finite state machines using a lookup table (it's not an OO way, but it works pretty well).

Strategy is used for the following [GoF book p. 316]:

  • many related classes differ only in their behavior. Strategies provide a way to configure a class with one of many behaviors.
  • you need different variants of an algorithm. For example, you might define algorithms reflecting different space/time trade-offs. Strategies can be used when these variants are implemented as a class hierarchy of algorithms [HO87].
  • an algorithm uses data that clients shouldn't know about. Use the Strategy pattern to avoid exposing complex, algorithm-specific data structures.
  • a class defines many behaviors, and these appear as multiple conditional statements in its operations. Instead of many conditionals, move related conditional branches into their own Strategy class.

The last case of where to apply Strategy is related to a refactoring known as Replace conditional with polymorphism.

Summary: State and Strategy solve very different problems. If your problem can't be modeled with a finite state machine, then likely State pattern isn't appropriate. If your problem isn't about encapsulating variants of a complex algorithm, then Strategy doesn't apply.

Static structure of the pattern

State has the following UML class structure:

PlantUML class diagram of State Pattern

Strategy has the following UML class structure:

PlantUML class diagram of Strategy Pattern

Summary: in terms of the static structure, these two patterns are mostly identical. In fact, pattern-detecting tools such as this one consider that "the structure of the [...] patterns is identical, prohibiting their distinction by an automatic process (e.g., without referring to conceptual information)."

There can be a major difference, however, if ConcreteStates decide themselves the state transitions (see the "might determine" associations in the diagram above). This results in coupling between concrete states. For example (see the next section), state A determines the transition to state B. If the Context class decides the transition to the next concrete state, these dependencies go away.

Dynamics of the pattern

As mentioned in the Problem section above, State implies that behavior changes at run-time depending on some state of an object. Therefore, the notion of state transitioning applies, as discussed with the relation of the finite state machine. [GoF] mentions that transitions can either be defined in the ConcreteState subclasses, or in a centralized location (such as a table-based location).

Let's assume a simple finite state machine:

PlantUML state transition diagram with two states and one transition

Assuming the subclasses decide the state transition (by returning the next state object), the dynamic looks something like this:

PlantUML sequence diagram for state transitions

To show the dynamics of Strategy, it's useful to borrow a real example.

PlantUML sequence diagram for strategy transitions

Summary: Each pattern uses a polymorphic call to do something depending on the context. In the State pattern, the polymorphic call (transition) often causes a change in the next state. In the Strategy pattern, the polymorphic call does not typically change the context (e.g., paying by credit card once doesn't imply you'll pay by PayPal the next time). Again, the State pattern's dynamics are determined by its corresponding fininte state machine, which (to me) is essential to correct application of this pattern.

by anonymous   2017-08-20

Three things I'd suggest:

Design patterns - Elements of reusable object oriented software - THE original design patterns book. Has examples in C++.

Head first design patterns - a very nice books detailing design patterns in Java. An enjoyable view.

Real world examples of design patterns in JDK - a terrific Stack overflow answer by BalusC.

by anonymous   2017-08-20

If you are looking for physical validation, what I usually find that helps is doing some prototyping. This gives you a good idea usually of any unforeseen problems that might be in your design and just how easy it is to add onto it. I would try to apply any design patterns possible to allow future scalability. Elements of Reusable Object-Oriented Software is a great reference for that. Here are some good examples that show before and after code using design patterns. This can help you visualize how design patterns could make your code more scalable as well. Here is an SO post about specific design patterns for software scalability.

by anonymous   2017-08-20

This is actually simple to do once you understand that DI is about patterns and principles, not technology.

To design the API in a DI Container-agnostic way, follow these general principles:

Program to an interface, not an implementation

This principle is actually a quote (from memory though) from Design Patterns, but it should always be your real goal. DI is just a means to achieve that end.

Apply the Hollywood Principle

The Hollywood Principle in DI terms says: Don't call the DI Container, it'll call you.

Never directly ask for a dependency by calling a container from within your code. Ask for it implicitly by using Constructor Injection.

Use Constructor Injection

When you need a dependency, ask for it statically through the constructor:

public class Service : IService
    private readonly ISomeDependency dep;

    public Service(ISomeDependency dep)
        if (dep == null)
            throw new ArgumentNullException("dep");

        this.dep = dep;

    public ISomeDependency Dependency
        get { return this.dep; }

Notice how the Service class guarantees its invariants. Once an instance is created, the dependency is guaranteed to be available because of the combination of the Guard Clause and the readonly keyword.

Use Abstract Factory if you need a short-lived object

Dependencies injected with Constructor Injection tend to be long-lived, but sometimes you need a short-lived object, or to construct the dependency based on a value known only at run-time.

See this for more information.

Compose only at the Last Responsible Moment

Keep objects decoupled until the very end. Normally, you can wait and wire everything up in the application's entry point. This is called the Composition Root.

More details here:

Simplify using a Facade

If you feel that the resulting API becomes too complex for novice users, you can always provide a few Facade classes that encapsulate common dependency combinations.

To provide a flexible Facade with a high degree of discoverability, you could consider providing Fluent Builders. Something like this:

public class MyFacade
    private IMyDependency dep;

    public MyFacade()
        this.dep = new DefaultDependency();

    public MyFacade WithDependency(IMyDependency dependency)
        this.dep = dependency;
        return this;

    public Foo CreateFoo()
        return new Foo(this.dep);

This would allow a user to create a default Foo by writing

var foo = new MyFacade().CreateFoo();

It would, however, be very discoverable that it's possible to supply a custom dependency, and you could write

var foo = new MyFacade().WithDependency(new CustomDependency()).CreateFoo();

If you imagine that the MyFacade class encapsulates a lot of different dependencies, I hope it's clear how it would provide proper defaults while still making extensibility discoverable.

FWIW, long after writing this answer, I expanded upon the concepts herein and wrote a longer blog post about DI-Friendly Libraries, and a companion post about DI-Friendly Frameworks.