headstart-system-design

The other day, a friend asked me on how I go about choosing a design pattern in a given scenario, because it was not always very clear.

Some design patterns are similar in terms of functionality (i.e. factory vs. builder)

I presented my intuitions via chat, and at the end of the discussion we both realized that with these intuitions for some of the design patterns in mind, choosing next time among them will be easier.

Hence, I thought of documenting and sharing it with everyone.

Factory

Say that you are shopping from a factory outlet of a clothing company. You will only get t-shirts based on the size grades i.e. S, M, L, XL etc.

Hence, single input from our side i.e. S, M, L, XL etc. will define the whole t-shirt.

Similarly, when you want to specify a single input argument like a keyword or an ENum, and get a variation of the main abstract class/interface TShirt created for you like SmallSizeTShirt, then you should go with Factory pattern.

Similar example is covered here, with abstract class/interface Person and its custom variations Villager and CityPerson created for use that are created on the basic of a single input, the enum PersonType.

headstart-system-design-factory-design-pattern-example

Factory Design Pattern in C#. Source: Wikipedia

Builder

Now say that instead of going to a factory outlet, you want to have something that fits you better, so you went to a tailor for custom tailored shirt.

Now, the tailor will take note of various other inputs like your chest size, your arm length, your shoulder length etc.

Hence, you can see that the tailor doesn’t have grades based on only one input like size, instead he has a number of input parameters and is makes unique shirts for each customer based on the input values for each of them.

Here, tailor is synonymous with a builder.

Hence, when there are multiple inputs from your side to construct a variation of the main abstract class/interface Shirt, use ShirtBuilder to return a CustomShirt for you based on various inputs.

Similar example is covered here, with ICarBuilder using various inputs like NumDoors, Colour, BrandName and ModelName and some code logic to construct a Ferrari 488 Spider Car.

headstart-system-design-builder-design-pattern-example

Builder Design Pattern in C#. Source: Wikipedia

Singleton

Suppose, you have a DB connection to initialize, and you want this DB connection to be established with your DB, and then every time you want to query for some data in a function, you get the same Connection object in establishedConnection state returned, to quickly query data.

In such scenarios where, not only do you want the same type of object to be returned, but you also want it to have a given state always, and for it to be a static method call to get that object, then you use the Singleton pattern.

Additional feature: A thread safe singleton can be created so that singleton property is maintained even in multi-threaded environment.  To make a singleton class thread-safe, getInstance() method is made synchronized so that one one thread can access it at a time.

headstart-system-design-singleton-design-pattern-example

Singleton Design Pattern supporting multi-threading in Java. Source: Wikipedia

Mixins

Suppose you are being told to make a system to accept pizza orders for a restaurant.

Here, class Pizza itself has many variations like ThinCrust, ThickCrust, ExtraCheese etc.

And, on-top of pizza you have a extra class like class Topping which has variations like Mushroom, BlackOlives, Pineapple etc.

Here, any Topping can go with any Pizza and vice versa.

Hence, for this kind of multiple inheritance requirement where:

  1. You want to provide a lot of optional features for a class.
  2. You want to use one particular feature in a lot of different classes.

For cases like these, you can use the Mixin pattern.

Note: Mixins only exist in languages that support multiple-inheritance. You can’t do a mixin in Java or C#.

headstart-system-design-mixin-design-pattern-example

Mixin Design Pattern (Pizza-Topping Example) in Python

headstart-system-design-mixin-design-pattern-example-output

Output for above example

Adapter

Suppose that you have to build an app interface for users to orders food from different restaurants. Here, menu shown to the user on your app is same for every restaurant, but the order information that each restaurant gets in slightly different.

In cases like these, where one common input has to be mapped to different kinds to input or actions taken we should use the Adapter Pattern.

Intuition is that adapters like charging adapter in real world do exactly the same thing. They send normal AC current coming at a fixed voltage-current range from the main socket into different charger pins for different devices like camera, phone, usb charger pin etc., all with their own voltage-current range.

Similar example is covered here, where different charging styles for LightningPhone and MicroUsbPhone are defined via interfaces.

Class IPhone implements only LightningPhone interface (it can only be charged via Lightning) and class Android implements only MicroUsbPhone interface (it can only be charged via Micro USB).

Now, the class LightningToMicroUsbAdapter helps to implement MicroUsbPhone interface and helps charge class Android with that, which otherwise was not possible.

headstart-system-design-adapter-design-pattern-example

Adapter Design Pattern in Java. Source: Wikipedia

Thanks for reading till the last bit!

I am Ravi Vats, a Software Engineer at Grab, and a Computer Science and Engineering Graduate from Ramaiah Institute of Technology, Bangalore.

My areas of interest are domains like Deep Learning, ML, Algorithms & Data Structures, Scalable & Concurrent Systems, Data Analysis & Visualization.

You can connect with me on my LinkedIn profile & follow my GitHub page.

Alternatively, I am also available on Twitter, Facebook, Instagram, Quora.

I hope you find this series interesting and resourceful. I am always open to any edits or suggestions to enhance the information provided in this series.

Cheers to learning! :)