Software design patterns

Bridge

Decouple abstraction from its implementation so that 2 can very independently

  • avoid permanent binding (so you can switch easily)
  • both elements can be extended
  • avoid recompiling one when there are changes on the other
  • 4 elements
    • abstraction (BO) - interface
    • redefined abstraction (customers BO) class
    • implementor (Data object) - interface
    • concrete implementor (customer data object) -class
  • example: client
    • Abstraction -> RefinedAstraction (Shape: Circle, Rectangle)
    • Implementor -> ConcreteImplementorA, ConcreteImplementorB (Drawing: DrawingA, DrawingB)
  • representation
    graph LR;
    A[Abstraction];
    B[Refined abstraction];
    C[Implementor];
    D[Concrete implementor];
    C-->A;
    B-.->A;  
    D-.->C;
  • consequences
    • decoupling
    • improved exetensibility
    • hiding implementation details from clients
  • Related pattern: adapter: unrelated classes working together

Builder

Splits construction and representation -> Factory vs BO

  • 4 elements
    • Director (builds something)
    • Builder (abstract) -> does the consctruction the director requires
    • ConcreteBuilder -> created externally, actually builds
    • Product (built by the Builder under the Director direction)
  • representation
    graph LR;
    A[Director];
    B[Builder: Concrete Builder];
    C[Product];
    A-->B; 
    B-->C;
  • consequences
    • Products internal representation
    • Control + isolation over construction process

Command: encapsulating invocation

Encapsulate method invocation - abstraction (e.g. single remote control for different devices: many on-off switches)

  • 4 elements
    • Client - creates command, chooses receiver
    • Receiver - knows how to perform the action
    • Concrete Command - binds action and receiver: execute() and undo()
    • Invoker (holds commands) –> ICommand (interface for all commands)
  • consequences
    • Package computation (loggng, transactional systems)
    • Decoupled job queues with “macro commands”
    • Bad stuff: time consuming, bloated commands
  • representation
    graph LR;
    A[Client];
    B[Receiver];
    C[Concrete Command];
    D[Invoker];
    E[ICommand];
    A-->B;
    A-->C;
    D-->E;

❗ Notes:

  • There can be a NoCommand (empty slot in a controller)
  • There can be an undo method (e.g. turn off lightbulb on controller)

Decorator

Structural, add behaviour to a particular object, as opposed to class objets (the others are unmodified)
(e.g. java.io.Reader/*component*/: InputStreamReader/*concreteComponent*/ and BufferedReader /*decorator*/)

  • 3 elements
    • Component (hang())
    • ConcreteComponent (hang()) //inheritance from Component
    • Decorator (hang()) //inheritance from Component, uses component
  • representation
    graph TD;
    A[Component];
    B[Concrete Component];
    C[Decorator];
    B-.->A;
    C-.->A;
    C-->B;
  • consequences
    • original object ‘not polluted’
    • flexible
    • doesn’t require source from original object
    • fewer classes than inheritance

Factory aka virtual constructor

Creational design pattern, as can’t anticipate which classes will be generated

  • 4 elements
    • Creator: abstract, provides full default implementation
    • Concrete Creator
    • Product
    • Concrete Product
  • representation
    graph LR;
    A[Creator: Concrete creator];
    B[Product: Concrete product];
    A-->B

Singleton

Unique instance without using an static class, so the class can be easily mocked and tested

1
2
3
4
5
6
7
8
9
10
11
public class Singleton{
private static Singleton instance;

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