Many books have been written in the past on the topic of software design patterns. The Design Patterns being one of the best. In today’s post, I’m going to skim through these patterns really quickly; just offering hint code (in java) for them.
Structural patterns are used to demonstrate the relationship between entities clearly.
Adapter
Adapter is a structural pattern and its purpose is to provide a bridge between two different interfaces to support a common contract. To illustrate, we have our way of adding two numbers and how we describe the inputs to a function.
We need to re-shape this for an external (or uncontrolled) contract now. They have their way of adding two numbers.
These each have their own implementations. We’d control MyAdderImpl, but we’d only ever see the interface TheirAdder; not their implementation.
To make an Adapter, we need to create an object that responds to TheirAdder but adapts to usage of MyAdder. To achieve this, we’ll use an adapter which just maps one interface to another. Here’s an adapter going from MyAdder over to TheirAdder.
The usage of these classes and interfaces now looks like this:
We’re using out adder implementation, but integrating with a function that expects their adder. So we adapt the values internally using our adapter, MyAdderToTheirAdderAdapter.
Facade
Facade is a structural pattern that allows a developer to produce a much simpler (or different) interface on top of a much more complex class. The whole idea is about making a cleaner interface against a complex object. The following class details a few of the things that you’d do when starting and stopping a car. Note how verbose these operations are:
I have already grouped these methods into two. The top set of methods apply to starting the car, the second are about stopping the car. We can create a much simpler interface across this object with a facade class:
From here, we no longer need to call purClutchIn then turnKeyOn then pumpFuel, etc. to start the car. We create a CarOperationFacade instance (passing in our Car instance) and the we can use start and stop.
Composite
The Composite pattern is about being able to treat different objects in the same manner. This is useful for when groups of object types need to be treated the same at some level. For this example, we’re going to create an expression tree for mathematical expressions. Everything in our expression language will be based off a root concept called an Atom. All an Atom does is emit its value:
We then create other sub classifications from this class like LiteralValue which will just represent a number and Operation which will allow us to define two Atoms concatenated by an operator:
Operation holding two further Atom references where it’s an Atom reference itself.
Bridge
The Bridge pattern is simply dividing out implementation details from the abstraction. If your class tree (hierarchy) has the potential to be too complex, the bridge pattern can assist in keeping your abstraction as implementation-dependency-free as possible.
As more drawing libraries came along, you’d be creating more Drawing derivatives directly tying the implementation to your abstraction. If we separate this out though, we can free the Drawing class of any derivatives.
Proxy
The proxy pattern is a structural pattern that provides a wrapper to access another object. It comes in a few different flavors:
Remote
Virtual
Protection
Remote proxies are used when the object is not in the local system-space; like accessible over the network or as a target of inter-process-communication (i.e. in a different JVM). Virtual proxies are used to defer work and make initialization more-lazy and finally the Protection proxy is about forming a layer that determines the safety of interacting with an object.
Creational patterns
Creational patterns aim to control the construction phase of an object. Constraining this process allows a developer to control the lifetime of their object system effectively.
Singleton
Singleton controls the instance count of a class in your application. These classes come in two different flavors: eager and lazy. An eagersingleton will instance itself as soon as the class’s static members come into scope:
One of the important pieces of this pattern is that the class’s constructor is marked private. This prevents integrating code from creating extra instances. This is exactly what this pattern aims to prevent.
The singleton reference is acquired through the use of getInstance.
A lazy variant on the class takes the initialization (construction) and places it into the singleton acquisition method getInstance.
This is handy when your constructor is performing work that you’d prefer to defer until you actually need the class. As a final note, the aim of this pattern is to control the developer’s ability to instantiate this class as such you’ll need to control any cloning/rehydration/deserialization techniques that developers may be able to use to inadvertently create another instance of your singleton.
Builder
The builder pattern gives the developer some syntactic sugar over the construction process, cleaning up massive constructor signatures.
You can now use your builder like so:
Factory Method
The factory method is a construction pattern, where a function provides the instancing of classes deriving from a common base.
parse in the XmlParser class is our factory method.
Abstract Factory
Taking the factory method a step further, we can abstract out the construction process for objects in the same category.
We can then start creating Vehicle objects and these will depend on the factory:
Prototype
The prototype pattern is a creational pattern that focuses on lowering the construction overhead. In order to achieve this in Java, the pattern will lean on java’s Cloneable interface.
The expensive load part is put in the static block above, only executed once. From there, objects are cloned into the sytstem.
Behavioral patterns
Behavioral patterns focus on the relationships between objects and how they communicate with each other.
Observer
The observer pattern is a behavioral pattern that provides a class the ability to publish and subscribe (pub/sub) state changes and messages.
Java already has the observer pattern baked in with Observer and Observable members of the java.util namespace. In this example, a cricket game is being played. Two batsmen are being observed by the scoreboard. So we define our batsmen with names and run totals; they also have the ability to score runs:
There would be heaps of observers, but in this case it’s going to be the scoreboard that observes the batsmen. Here’s our scoreboard:
Each time that a batsmen scores runs with scoreRuns, the scoreboard gets notified; we at least it does if we use addObserver:
Mediator
You can use the mediator pattern to loosen the coupling of your objects. It’s the job of the mediator pattern to define how a set of objects interact.
When you have many objects performing operations on each other, the direct dependency is removed by abstracting your operations out into an interface. The interface is your mediator that satisfies all of the now disparate parts of your object system.
In this example, the program is managing a baseball game. The following interface denotes all of the actions that can go on in our game.
In order for an object to participate within this system, we need to allow it to set a mediator:
All of our system objects now become BaseballParcipant derivatives. They, as usual, hold their actions that they manage (batter hits a ball, fielder catches a ball, etc.) but the implementation of these actions enforces its side-effects through the usage of the BaseballMediator instance that gets set.
Finally, the mediator gets defined which marshals the interactions between our system objects:
Chain of Responsibility
The chain of responsibility pattern serves as a request forwarder. A request that you supply to the chain moves through the chain itself until the contents of the request match the implementation. If you needed to perform some processing on a Executive, Manager, Supervisor or Employee you would start by creating your processing contract:
The important part of this contract really is the setHandler. It’s going to to simulate our chain for us:
Manager, Supervisor and Employee implementations would look very similar to Executive.
Building the chain now looks like this:
Flyweight
The flyweight pattern takes the construction of objects and caches instances to save on the construction process. Really useful when you have a large volume of objects that are quite similar.
Momento
The momento pattern is all about taking snapshots of an object so that you can provide undo functionality to your class.
Template
The template pattern is about putting a sequence of instructions that developers can hook to:
In this example, toString traverses a tree but offers the developer getLeafText to control the leaf’s representation in the string.
State
The state pattern will allow you to explicitly manage state changes in your objects by defining the equivalent of a cartesian map of functionality. The CarState interface in the following example lays out all of the actions that our objects will perform.
For each state that we define, we now need a concrete implementation of the CarState interface:
Our Car implementation itself will use this state interface to define its structure, but we’ll also define a variable (of type CarState) for every state that the car can be in.
Strategy
The strategy design pattern is more in the name than anything else. From a common base, you’ll create derivatives that a executioner will use to perform an action.
Being able to interpolate values from 0 up to 1 by means of linear or trigonometric methods is an implementation detail for the strategy pattern.
Command
The command design pattern is all about dispatching messages (or instructions) from an invoker to a receiver. In sorts, you can think of it a message pump:
Interpreter
The interpreter pattern is about making an interpreted languages (and resulting execution environments). There are a lot of different tools already available to take language agnostic gammar definitions and output source code that will interpret this.
Decorator
The decorator patterns allows a developer to separate commonly described attributes into smaller class implementations. These smaller pieces are the composed together (or the original instance is decorated) so that we end up with an object that has more extras.
The Car interface defines what’s important to us about the car, where as CarDecorator is how our system explains the pieces that we’re going to decorate our Car with.
Paint and Wheel are both concrete decorations and can be applied like so:
Iterator
The iterator pattern allows us to treat a sequence of objects in a uniform way. The action of traversal is supplied in a common way so that sets can be enumerated in similar ways.
In java, this is achieved using the Iterator interface.