Design Patterns used most often

Below some of the design pattern we use most often, their purpose and examples.

Factory Method

Factory method – it’s a creational design pattern that allows subclasses to decide which classes to instantiate, removing this concern from the caller level.
The factory method is typically abstract, and subclasses implement their own suitable version, as long as they return an object of the requested interface.

For example, this method may have this signature:

public abstract Trade createTrade(String type)

Trade here is an interface, and we may have FxSwapTrade, FixedIncomeTrade, CommodityForwardTrade etc.
The superclass that defines abstract factory method uses the Trade type in all of its methods, and doesn’t need to know the exact subclass. Most importantly, it doesn’t need to know the complexity of creating an instance of a specific trade – be it a single-legged trade or a swap, FX or Commodity or something else.
Calling createTrade(“FxSwap”), createTrade(“FixedIncomeSwap”), createTrade(“CommodityForward”) would simply return a Trade object, and the caller could use it in its methods.

Factory method: Creator class details

The abstract class that declares createTrade could be called TradeProcessor, and it could have subclasses called FxTradeProcessor, FixedIncomeTradeProcessor, CommodityTradeProcessor. This design pattern decouples the Trade creation from the client by hiding the specifics and the internals of creating trades for different asset classes, so subclasses hide this complexity in their own versions of createTrade().
Specific client only needs to instantiate a suitable TradeProcessor and call TradeProcessor.createTrade().

Factory method: main advantages

Decoupling the creator of the object from the object itself (TradeProcessor doesn’t care how Trade is created, making it easy to change Trade implementation or add Trades of a new asset class)
Also, by placing all the complexity of the object creation in one method we avoid duplication of code and make maintenance easy.

Decorator

The Decorator usually extends the class that’s needed by the client, and this extended class also contains the instance of the original class. In fact, the decorator follows the Adapter Pattern.
By extending the class you would get the same interface as the wrapped object, and when the client calls the method that needs to perform some work in the decorator class, that method internally calls the wrapped object’s method – delegating the actual work to the base class.
Note that extending the superclass is done to get the type matching only – not to inherit the behavior. So typically you’d subclass the abstract class – not one of it’s implementations.
So we are using Composition, not Inheritance – and this allows us a lot more flexibility, without fear of inadvertently breaking something in one of the subclasses when we need to change a superclass.

Decorator: the purpose

The purpose of the decorator class is to modify the behaviors of the wrapped class – examples could be:

  • Pre- or post-processing method arguments or result, potentially enriching or modifying it
  • Do some extra work or cleanup around the method in need
  • Adding synchronization to the execution of the original class’s methods
  • Adapting the original class’s interface to a new interface as required by a new client
  • Hiding complexity of the original class
  • Adding extra logging to the called method

Decorator: the benefits

We can achieve the same effect as extending the superclass – adding new behavior to the object, but without the rigidity that inheritance brings with it

Decorator: Examples in the real world

java.io package classes use Decorator pattern a lot: FileInputStream, BufferedInputStream, CipherInputStream, LineNumberInputStream etc. – each adding new functionality using Decorator pattern

Singleton

Singleton is used for instance control, it prevents clients form creating more than one instance of itself. Singleton also provides a global access point to itself.
When you need to make sure that there’s only one instance of an object in memory, and all clients have to deal with this object alone.

Singleton: usage

It’s used for critical resource management, like application configuration, DB connection pools, caches, thread pools.

Note: Singleton is unique per class loader – so if you are using more than one class loader, you need to make sure that you specify classloader when dealing with the Singleton.

Code example:

public class Singleton 
{
	// may also eagerly create an instance if performance is an issue in multithreaded environment, 
	// in such case just return the already ready instance from getInstance()
    private static Singleton instance = null; 
  
    private Singleton() 
    { 
        //... initialization code 
    } 

    public static Singleton getInstance() 
    { 
        if (instance == null) 
            instance = new Singleton(); 
  
        return instance; 
    } 
}

Chain Of Responsibility

Problem: you want to give more than one object a chance to handle the request.
This pattern is designed to solve a problem when you can potentially have more than handler and you don’t know which one it is.

Examples would be GUI event handler, java servlet filter etc.
Each handler object either knows how to process the request or passes it along the chain. This way when we pass the request to the chain, we don’t need to know who will handle it, decoupling sender from the receiver.

Typically the handlers will implement the same interface.
Also, it’s expected that the request may go through all the handlers and not get handled – handling is not guaranteed.
You can compose chains at runtime, using different handlers without coupling your code to their order or concrete classes.
You can add new handlers into the chain without breaking the existing client code.

Chain Of Responsibility: Example

You need to be able to handle an credit breach when the trade comes in, and there are several levels of approving it. Level one is automated, it rejects the trade and passes it along to Level two for an intervention and potential approval, and then it may go to Level three for a final credit override. Each level may be able to authorize a different notional size.

Chain Of Responsibility: implementation

The handler class would typically have a method setNextHandler() to define the next handler in case the request cannot be handled locally.
There would be a HandlerManager class that arranges the handles in order when the application starts.
The work starts with sending the request to the first in chain handler.

Proxy patern

Motivation of the Proxy pattern is to make remote object’s high complexity look simpler to the client. As a result, the client may not need to go through the complexity of setting up authorizations, instantiating connections etc. required by the target class. Proxy takes care of that.

Proxy class will have the same interface as the target object.
Proxy deals with the target object and hides the complexity of doing this form the client.
When compared to Decorator pattern, Proxy doesn’t add any extra functionality. Also, Proxy is the only way of accessing the target object for the client – while the Decorator doesn’t block client from accessing the target object directly.

Use cases for the Proxy pattern

  • Remote proxy, accessing an object in a different address space
  • Count limit proxy, where there’s a need to control how many clients access target object at a time
  • Synchronization proxy – when access to the target object needs to be safe in concurrent environment
  • Firewall proxy – when there’s a need to limit clients from accessing certain target objects