Tag Archives: Design Patterns

Behavioral Design Patterns

After discussing creational and strutural design patterns, lets go over behavirol design patterns.

Template: allows one to create a template of code or algorithm which will provide guidelines for different implementations.

Strategy Pattern: helps selection of an algorithm at runtime.

Observer: A pattern that helps manage event-based communication (publish-subscribe). Objects being observed notifies observers about the event, which can then take required actions.

https://en.wikipedia.org/wiki/Observer_pattern

Memento: A pattern is used to restore the state of an object to a previous state.

Example: https://www.geeksforgeeks.org/memento-design-pattern/

Chain of Responsibility: At runtime, command objects are selected to execute responsibilities. One common example is FilterChain used with servlets where multiple filter commands are executed on receiving a Request.

The chain-of-responsibility pattern is structurally nearly identical to the decorator pattern, the difference being that for the decorator, all classes handle the request, while for the chain of responsibility, exactly one of the classes in the chain handles the request. This is a strict definition of the Responsibility concept in the GoF book. However, many implementations (such as loggers below, or UI event handling, or servlet filters in Java, etc.) allow several elements in the chain to take responsibility.

https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern

Command Pattern: creates objects that encapsulate actions and parameters

interface Command
{
    public void execute();
}

Example: https://www.geeksforgeeks.org/command-pattern/

Iterator: Iterator helps accesses the elements of an object sequentially without exposing its underlying representation.

interface Iterator
{
    boolean hasNext();
    Object next();
}

Example: https://www.geeksforgeeks.org/iterator-pattern/

Interpreter: A pattern that helps you parse and evaluate sentences in a language.

Example: https://www.geeksforgeeks.org/interpreter-design-pattern/

Mediator: Two objects are decoupled as they do not communicate to each other directly, but via a mediator.

https://en.wikipedia.org/wiki/Mediator_pattern

Unlike adapter where the communication is one way and caller is aware of provider, in mediator a middle layer helps both parties to communicate.

Visitor: Implemented using accept() and visit() methods, the component being visited needs to implement accept method and visiting component implements visit method.

Visitor Pattern UML Diagram
https://www.tutorialspoint.com/design_pattern/visitor_pattern.htm

State: An object can manage its behavior based on state. For example, a mobilealert object can have state as ring, silent, vibrate and based on state its bevior is changing. Here is a good example implementation https://www.geeksforgeeks.org/state-design-pattern/

https://en.wikipedia.org/wiki/State_pattern

Structural Design Patterns

After discussing creational design patterns in the last post, let’s go over structural design patterns.

Adapter: One of the most common structural patterns that helps two incompatible components talk to each other. For example, for a caller that communicates in JSON, but the provider service only understands XML, an adapter helps in this situation.

Composite: To manage the cases where there can be a cyclic relationship between objects, for example, a Manager himself is an Employee, and at the same time Manager has a relationship (manages) other employees.

Facade: Hide complex implementation details from the caller, which calls the facade. The facade layer then communicates with various other implementing components and returns the final response back.

Proxy: A common pattern hiding the actual implementation from the caller client. The client calls the proxy class or proxy layer, which in turn communicates with implementing component.

Bridge: The pattern that helps decouple an abstraction from its implementation.

Flyweight: The flyweight pattern helps reuse objects where ever possible and only creates a new object if the object is not available.

It sounds a bit overlapping with the object pool pattern, but there are significant differences. An object pool is a creational pattern whereas flyweight is a structural pattern. Object pool makes sure objects of the same type are pooled, whereas flyweight takes care of different object implementations, stored as a singleton.

Example: https://www.tutorialspoint.com/design_pattern/flyweight_pattern.htm

Decorator: The core component is decorated or enhanced by additional decorator features on the fly.

Example: https://www.tutorialspoint.com/design_pattern/decorator_pattern.htm

https://en.wikipedia.org/wiki/Decorator_pattern

Creational Design Patters

Let us revisit creational design patterns.

Singleton pattern: Most commonly used creational pattern where we want to make sure a single object is maintained for a class.

Factory Pattern: Representing a real-world scenario, one can let the factory create objects of multiple types inheriting similar features, for example, a car factory building sedans as well as hatchbacks.

Abstract Factory Pattern: Additional layer above the factory pattern, for example, a vehicle factory has two sections a car factory and a bike factory, and the car factory further produces multiple types of cars.

Prototype Pattern: Object prototypes are created in advance, which is clones on demand and a new object is returned.

Builder Pattern: A commonly used pattern (DocumentBuilder and StringBuilder in Java), that breaks object creation activity into multiple steps.

Object Pool Pattern: The creation of an object can be an expensive affair for complex objects, a very common example is database connections. In such cases, the object pool pattern helps in reusing the objects once created, hence improving the performance of the system.

The object pool pattern is a software creational design pattern that uses a set of initialized objects kept ready to use – a “pool” – rather than allocating and destroying them on demand. A client of the pool will request an object from the pool and perform operations on the returned object. When the client has finished, it returns the object to the pool rather than destroying it.

https://en.wikipedia.org/wiki/Object_pool_pattern

Design: Uber

In this series of popular system designs, I will take up design for a taxi aggregator service like Uber. Please note that the designs I share are based on my understanding of these systems and might not be the same as actual designs.

Before Getting on with Designs, let’s list down the requirements

Functional Requirements

  • User (Rider) should be able to create an account
  • Driver should be able to register
  • Rider should be able to view cabs availability in near proximity along with approx ETA
  • Rider should be able to request for a cab
  • Driver should be able to receive a trip request.
  • Driver can accept the request (Assumption: Multiple drivers will receive the request and one will accept)
  • Trip starts when rider boards the request.
  • When trip ends, Rider can make the payment and receive a receipt.
  • Rider can rate the Trip / Driver
  • Rider can view Trip history
  • Driver can view Trip history

Non Functional Requirements

  • Availability
  • Scalability
  • Performance
  • Consistency
  • Localization

Services to be created

  • User Management Service
  • Driver Management Service
  • Cab Search Service (Takes Riders location and finds nearby cars)
  • Ride Request Service (Rider’s request is shared with drivers for acceptance)
  • Trip Management Service
  • Trip History Service

Database Requirements

  • User Data
  • Driver and Cab Data
  • Cab Location Data
  • Trip Data (Current and Historical)

A high-level design might look like

An important question one needs to answer is about the Cab locator service works. The class way of GeoHashing should be used, where the whole area will be thought of as square boxes. Say a user is at Lat, Long position, we will try to find all the boxes around the current location within a given radius. And then find all the Drivers available in these Geo boxes.

Some interesting alternative representations

https://www.codekarle.com/system-design/Uber-system-design.html
Uber-System-Design-High-Level-Architecture
https://www.geeksforgeeks.org/system-design-of-uber-app-uber-system-architecture/

Building Reactive Systems

In today’s world, we are always striving for building applications which can adapt to constantly changing needs. We want our systems to flexible, resilient, scalable and withstand end user’s high expectations.

Considering these needs, a Reactive Manifesto was put together, with best practices which will help us build robust applications. Following four pillars makes a strong base of reactive application.

1. Responsive
2. Resilient
3. Elastic
4. Message Driven

You can see none of these concepts are new in nature, and you might be already implementing them in the applications you build. Reactive Manifesto brings them under one umbrella and emphasizes their importance. Let’s take a look at these pillars one by one and see what all well-known patterns we can use to implement each of them.

Responsive: An application is responsive if it responds to the user in a timely manner. A very simple example is you clicked on a button or link in a web application, it does not give you a feedback that button was clicked and the action gets completed after few seconds. Such an application is non-responsive as the user is left guessing if he is performing the right action.

Some of the well-known practices and design patterns which help us make sure if the application is responsive
– Asynchronous communication
– Caching
– Fanout and quickest reply pattern
– Fail-fast pattern

Resilience: An application is called resilient if it can handle failure conditions in a graceful manner.

Some of the patterns that help maintain resilience
– Circuit breaker pattern
– Failure handling pattern
– Bounded Queue Pattern
– Bulkhead Pattern

Elasticity: An application is called elastic if it can stand increase or decrease in load without any major impact on overall working and performance.

Some of the practices and patterns to implement elasticity
– Single responsibility
– Statelessness
– Autoscaling
– Self-containment

Message Driven: An application which uses message driven communication makes sure we are implementing various components and services in a loosely coupled manner. This helps us keep our components scalable and makes failure handling easy.

Practices used to implement Message driven communicaiton
– Event driven
– Publisher Subscriber pattern
– Idempotency pattern

I have covered some of these patterns in details in my book on Design Patterns and Best Practices.

SOLID Principles for object oriented design

There are many best practices and principles figured out by developers and architects for object oriented design. Robert Martin has intelligently put a subset of these good practices together, and gave them acronym SOLID which helps easy remembrance.

Single responsibility principle: A class should handle only one single responsibility and have only one reason for change. For example a class “Employee” should not change if there a change in project or some reporting details.

Open Closed principle: Code should be open for extension but closed for modification. If you want to add a new type of report in the system, you should not be changing any existing code. More here

Liskov substitution principle: “objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.” So if we have Employee class, which is extended by Manager. We should be able to use Manager instead of Employee and all the Employee methods like calculate Salary, generate annual report etc should work without any issues. Say if there is an object like “ContractWorker” that does not support a few functions of Employee like annual report, one should be careful not to make it subtype of Employee.

Interface Segregation principle: “no client should be forced to depend on methods it does not use”. Coming back to previous example, if “ContractWorker” does not need to support annual report, we should not force it to implement an iEmployee interface. We should break the interfaces say iReport and iEmployee, iEmployee can extent iReport and iContractWorker should implement only iReport. iReport can further be divided into reporting types if required.

Dependency Inversion principle: This one seems to be one of my favorite as I have written about it here, here, here and here. This one indeed is one of the most important design patterns which can be followed to make the code loosely coupled and hence making it more maintainable (golden rule- low coupling + high cohesiveness). In traditional programming, when a high level method calls a low level method, it needs to be aware of the low level method at compile time, whereas using DI we can make high level method depend on an abstraction or interface and details of implementation will be provided at run time, hence giving us freedom to use which implementation to be used. Coming back to my previous example, I can have multiple implementations of Employee Reporting, iReport. Some implementation need and excel report, other might need a PDF reporting, which can be decided at runtime.

Inject Or Autowired

Sometimes in a Spring framework code, we see the keywords @Inject and @Autowired being used interchangeably. Simply putting it @Autowired is Spring specific annotation for implementing Dependency Injection, whereas @Inject is part of Java EE 6 specification, hence more generic.

JSR 299, Java EE 6 specification, provided a feature called Contexts and Dependency Injection (CDI). http://docs.oracle.com/javaee/6/tutorial/doc/giwhb.html.

JSR 330, more specifically talks about Dependency Injection. https://dzone.com/articles/what-relation-betwe-there

A more elaborated explanation on usage of various DI annotations – http://blogs.sourceallies.com/2011/08/spring-injection-with-resource-and-autowired/#more-2350

Inversion of Control: Dependency Injection vs Dependency Lookup

Inversion of Control is a principle which recommends moving unwanted responsibilities out of a class and letting the class focus on core responsibilities, hence providing loose coupling.

There are two basic ways in Java to provide IOC- Dependency Injection and Dependency lookup.

As the name suggest, Dependency Injection is where the dependency is injected from outside the class, and class is not worried about details – http://kamalmeet.com/coding/more-on-dependency-injection/

Dependency lookup is where class itself looks up for dependency and chooses appropriate implementation. Use of JNDI lookup for proper bean of datasource is a good example.

InitialContext ic = new InitialContext();
DataSource ds = (DataSource) ic.lookup(“jndiName”);

Double Check Locking- pattern

Double check locking pattern is used for double checking the condition before acquiring a lock on an object. This helps reducing unneccary locks.

To understand lets take a simple example of creating a singleton object.

public static MySingleton getInstance()
{
if(null==mysingleton)
mysingleton=new MySingleton();
return mysingleton;
}

The challenge with above code is that it is not threadsafe. So we might end up creating multiple objects of MySingleton in case of multithreaded environment. So we will add synchronization.

public static synchronized MySingleton getInstance()
{
if(null==mysingleton)
mysingleton=new MySingleton();
return mysingleton;
}

Though we have saved our code from multi threading, we have added additional load of synchronization, i.e. each thread will have to wait for previous thread to finish processing of this method before entering into it. The actual error case will occur only for first time, i.e. when mysingleton object is null, we would like to stop other threads to execute the block. So to optimiza the code, we will use a technique called double locking.

public static synchronized MySingleton getInstance()
{
if(null==mysingleton)
{
synchronized(MySingleton.class) {
if(null==mysingleton)
mysingleton=new MySingleton();
}
}
return mysingleton;
}

You can see we are applying synchronized block only when we are sure that we are in a case we want to stop multiple threads from going ahead, rather than blocking threads all the time.

http://en.wikipedia.org/wiki/Double-checked_locking