Design Patterns

Design patterns provide a fundamental foundation to building maintainable and scalable software. Understanding how the patterns work, why they provide a benefit, and when to use them helps to ensure that software is built from reusable object-oriented components. In this Refcard, we will dive into the concepts that underpin design patterns, look at the 23 Gang of Four (GoF) patterns that brought about the proliferation of design patterns, and review some common patterns that have evolved since the GoF patterns were published.

Free PDF for Easy Reference

refcard cover

Software Engineer, IBM Table of Contents

Introduction

Design patterns are solutions to common problems seen in software development. They are a foundational concept that both novice and advanced developers must continuously study and practice. In this Refcard, we will dive into the concepts that underpin design patterns and look at the 23 Gang of Four (GoF) patterns that brought about the proliferation of design patterns.

We will then look at some common patterns that have evolved over the years since the GoF patterns were published in 1994, as well as some resources that will help us understand the GoF patterns — and design patterns in general — more intuitively.

Fundamental Concepts of Object-Oriented Design

Before we dive into the GoF patterns, we must first understand the fundamental concepts of object-oriented (OO) design and look at two important considerations that provide a groundwork for all OO software patterns. Understanding the GoF design patterns requires a foundational understanding of OO design. Three of the fundamental concepts shared by all OO design patterns — and the GoF design patterns, in particular — are abstraction, interfaces, and polymorphism.

Abstraction is the removal of unnecessary details and the focus on pertinent details for a given context. For example, when we look at a car, we see doors, body panels, windows, wheels, and the like. If we focus on the wheels, we may go into a deeper level of abstraction and see rubber tires, metal rims, and air. Another level deeper, and we may focus on composites in the rubber compound or the nitrogen and oxygen particles bouncing within the tire that constitute tire pressure. The level of abstraction we select will depend on the particular problem and the problem's context.

Interfaces are the highest form of abstraction in OO design. Interfaces represent what an object can do — through methods — while hiding the details of how it does it. For example, the interface for a car, Car , may be limited to a start() and driveTo(Location) method, neither of which provide any details about how a particular car is started or can be driven to a particular location.

Implementations of this interface (called concrete classes) are then created, which provide these details, but clients interacting with the Car interface are unconcerned with these details. This encapsulates the details and allows clients to focus on the inputs and outputs of the methods rather than the particular details of how they are performed.

Polymorphism is the ability of an object to be treated as multiple types at the same time. There is static polymorphism, which uses method overloading, and dynamic polymorphism, which uses method overriding. Most design patterns focus on dynamic polymorphism, where a client calls the methods of an interface while unaware of the actual implementation being used. For example:

Vehicle vehicleA = new Sedan(); Vehicle vehicleB = new Truck(); vehicleA.drive(); vehicleB.drive();

In this case, when drive() is called on vehcileA , it will use the Sedan , and when drive() is called on vehicleB , it will use the Truck implementation.

Considerations

In addition to OO design principles, there are two additional points we must consider before we can understand different design patterns: delegation and inheritance vs. aggregation.