Design Patterns

Here are code examples on my GitHub account of the below design patterns and more.

Here, I have several class diagrams of various systems that utilize some of the design patterns explained below.

Below, I have included short descriptions of the standard design patterns.

Composite
Proxy
Singleton
Adapter
Bridge
Decorator
Facade
Factory
Observer
State
Strategy
Visitor
Command
Iterator

Composite

It provides a mechanism to operate on a collection of objects uniformly.

For example, you can work on a portfolio as a collection of positions where you can operate on the portfolio, which internally operates on the collection of positions.

Work on a hierarchy of objects where the order can be arbitrarily deep.

Proxy

It provides an interface that is used to access another object. It can be used when you want to add security in the interface before accessing the object or if the object lives in a remote process.

Singleton

Use when you want to create only one instance of a class.

Singleton’s create problems with testing because you can’t control the life cycle of the singleton.

Adapter

It allows existing classes to work with other classes with incompatible interfaces.

Bridge

It is used to decouple the class’s interface from its implementation so that the two can vary independently.

Decorator

It is useful when you have a list of classes with additional properties. The cartesian product of classes and their properties will lead to many classes. So, instead of using inheritance, we can use a collection of composed objects to provide the desired behavior.

For example, an olive thin-crust pizza can be constructed by a decorator via :

  1. Creating a thin-crust pizza
  2. Making a cheese pizza from the thin crust pizza (started created in 1)
  3. Create an olive pizza by using the cheese pizza (already created in 2)

Facade

A facade pattern creates a simplified interface over various complicated interfaces.

For example, a facade pattern is used by a compiler to provide a simple interface over :

  1. Tokenizer (Tokens)
  2. Parser (Abstract syntax tree)
  3. Intermediate representation (IR Code)
  4. Optimize
  5. Code generator
  6. Linker

Instead of dealing with the above complexity, users can use the simplified interface provided by the facade (compiler).

Factory

The factory method allows a clean way to construct a set of classes. The behavior of construction can be changed by varying the actual construction factories.

A similar pattern is called Abstract Factory, which is used to construct a group of similar objects together based on parameters that can control the construction of objects based on the parameters.

Observer

It is used to keep track of the state of a class.

For example, many applications may be interested in knowing when the geo location of the phone changes. For this case, we can use the visitor pattern where apps can register with the OS to get notified of the new geo-location when it changes.

State

State pattern is used to have different behaviors based on the state of an application. The behavior is controlled by a class that handles the behavior of a specific state.

For example, a state pattern can manage the ring behavior of a phone efficiently. The state of the phone can be silent, vibrate, or ring. Then, depending on the state of the phone, the appropriate behavior is executed by the given state.

Strategy

Strategy pattern allows dynamically choosing the algorithm to use at run time based on the use case.

For example, a file compression routine can use various compression algorithms and choose the appropriate one based on need (choose zip or rar based on need.)

Visitor

Visitor patterns can be used where you have a lot of objects (i.e., file types) and need to add methods to the files frequently. Because there are many file types, methods will need to be added to many files, which is messy.

Here, a visitor pattern can add an abstract visitor class with a method to visit each file type. When we add a new way, we can add it to the visitor rather than adding it to each file.

We have a concrete visitor class for each method (i.e., print). The concrete class has methods to handle the appropriate operation for each file type. The correct instance of the method will be called because the method gets passed to the correct file type as a parameter.

Command

Encapsulates a request as an object and thereby provides the ability to execute or roll back the command.

Iterator

An iterator is a design pattern that allows traversing a container without accessing the container elements directly. This allows code to treat various containers similarly and thus decouple code from container-specific interfaces.