Programming Design Patterns Summary

Here is a quick summary of design patterns that everyone should know:-

Factory Patterns

  • Builder - Separate the creation of a complex object from its representation so that we can use the same construction process to create different representations.
  • Abstract factory - Using a interface to create families of related or dependent objects without specifying their concrete classes.
  • Factory method - Define a interface for creating an object but let their subclasses decide how they are implemented.
  • Prototype - Design a prototype instance and use it to create new objects by copying this prototype.
  •  Singleton - Create only one instance of a object and ensure that it is globally accessible.

Structural design patterns

  • Adapter - Create a interface that lets you interact with another interface the client expects, it lets incompatible classes work together.
  • Builder - Decouple the abstraction from its implementation so the two can vary independently.
  • Composite - Compose objects into tree structures to enable recursive composition. 
  • Decorator - Add additional responsibilities to an object dynamically.
  • Facade - Provide a unified interface to a set of interfaces in a subsystem. Makes it easier to use subsystems by using this higher level interface.
  • Flyweight - Support the sharing of large number of fine grained objects efficiently.
  • Proxy - Provide a placeholder for another object to control access to it. 

Behavioral design patterns

  • Chain of responsibility - Avoid coupling the sender from the receiver by allowing other objects a chance to handle it.
  • Command - Encapsulate a request as a object and let you parametrize with different request, queues or logs. Supports undoable operations.
  • Interpreter - Given a langauge, define a representation for its grammar along with interpreter that uses the representation to interpret sentences in the language.
  • Iterator - Provide ways to access items in a object in a sequential manner without exposing its underlying representation.
  • Mediator - Promotes loose coupling between objects and prevents them from referring to each other directly, encapsulates how a set of objects interact.
  • Memento - Without violating encapsulation, capture and externalize and objects internal state so that it can later be returned to this state later.
  • Observer - Define a one to many relationship between objects so then when one objects state changes all its dependencies are notified and updated.
  • State - Allow an object to be able to change its behaviour when its internal state changes so that it appears that the objects class has changed.
  • Strategy - Define a family of algorithms, encapsulate each one and make them interchangeable. Allows you to vary the algorithm independently from the clients that use it.
  • Template method - Define a skeleton of algorithm in a operation whilst deferring some steps to client subclasses. Allows you to redefine steps in the algorithm without changing the algorithms structure.
  • Visitor - Represent an operation to be performed on elements of a object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

 

[C# 7.2] Readonly Structs

Lets look at some new features recently release with the C# 7.2 minor releases, I will explain what it was trying to solve and how.

A bit of background, with structs in C#, its possible to expose public properties as well as setting private properties, the example below shows its structure:-

public struct Document
{
public string Title { get; set; }
public string Author { get; set; }

public Document( string title, string author )
{
Title = title;
Author = author;
}

public void ChangeDocument(Document newDoc){
this = newDoc;
}
}

 So from this we can see that it causes the struct to be in a mutable state whereby we allow the public properties to be modified using the "this" key.

Moving for a more immutable solution we can leverage the new C# 7.2 feature and decorate the struct with readonly.

public readonly struct Document
{
public string Title { get; set; }
public string Author { get; set; }

public Document( string title, string author )
{
Title = title;
Author = author;
}

public void ChangeDocument(Document newDoc){
this = newDoc;
}
}

 This will cause a compile error with the this keyword as a result.

The code can then be shortened to refactor towards immutability as follows:-

public readonly struct Document
{
public string Title { get; set; }
public string Author { get; set; }

public Document (string title, string author)
{
Title = title;
Author = author;
}
}

 

So in the usage in the code, it can be updated from:-

var doc = new Document();
doc.Title = "SomeTitle";
doc.Author = "SomeAuthor";

to:-

var doc = new Document
{
Title = "SomeTitle",
Author = "SomeAuthor"
}

 

So with this new change, it encourages developers to program with immutability in mind and even though the default parameterless constructor is still available, readonly will cause a compile time error.

 

Using the Priority Queue Pattern with our Microsoft Azure Solution

In a recent programming conundrum, I was trying to find a way I could promote certain customer queries to the top of the support list compared to that of a general nature. The limitations with the azure service bus is the inability to add priority headers to packets being placed into the queue, so that was a nonstarter.

With queues, they work on a FIFO (first in first out) nature and allow developers to decouple the components that are adding items to the queue from those that are performing tasks against it.

The queue in general was great at adding items to be processed in an asynchronous nature, however with recent updates to our SLA requirements we were encountering issues where non urgent request were creating a service bottleneck in our system.

The solution that we decided to try to implement was the priority queue on the Microsoft Azure using a few message queues and multiple consumer instances against those queues.

 

The plan was to identify the data being processed from the producer side, and based on that generate the relevant packets and use the message router to send the packets of data to the corresponding queue. In our example, we spawn 3 types that were being used (High, Medium and Low priorities).

In essence the queue would function as normal with the producer – consumer peeking and deleting messages as they are being added to the queue. The difference and where the priority queue pattern comes into play is the number of consumers being allocated to subscribed to the particular queues. With the high priority queue, we have 5 instances competing to consumer the messages. With the medium we had 3 and with the low we had one. The result of this is that the high priority queue would be able to handle many more requests and faster than the other queues, and therefore would be able to provide a far better SLA time and meet expectations.

 

priority-queue-separate

 

For more information on it you can read https://docs.microsoft.com/en-us/azure/architecture/patterns/priority-queue

You can also find the implementation example on Github