What are Design Patterns and Why you should learn them?

What are Design Patterns and Why you should learn them?

What is a Design Pattern?

Christopher Alexander says, "Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice". Even though Alexander was talking about patterns in buildings and towns, what he says is true about object-oriented design patterns. Software design patterns are expressed in terms of objects and interfaces instead of walls and doors, but at the core of both kinds of patterns is a solution to a problem in a context[1].

The definition of Design Patterns in Wikipedia reads:

A software design pattern is a general, reusable solution to a commonly occurring problem within a given context in software design. It is not a finished design that can be transformed directly into source or machine code. Rather, it is a description or template for how to solve a problem that can be used in many different situations. Design patterns are formalized best practices that the programmer can use to solve common problems when designing an application or system.

  • This definition mentions that a design pattern is general, and can be applied to multiple different aspects of your software design regardless of the type of application you are working on.
  • It also mentions that it is reusable, which means that you can reuse them throughout your application many different times, and in many different scenarios. This means that you need to learn the pattern once, and then you can use it in many different places when applicable.
  • It also mentions that it is a formalization of best practices that the programmer can use to solve common problems. There are many different patterns to do many different things, and it has taken brilliant minds from many different people who have come together and said this is the best way to solve this problem in the cleanest way possible.

Why do we learn Design Patterns?

Learning design patterns is a fairly straightforward thing to do. The process of learning design patterns is much easier than learning when/where you should use them.

The biggest problem that most people have is that they learn about design patterns, and they are amazed by them and want to use them all over the place to make their code so much cleaner, and they start to through design patterns into areas where they don’t really fit, or maybe overkill, and not using them would be better. So learning when to use them is the hard part about design patterns!

Learning design patterns help you have a fullistic view of how to write cleaner and more reusable code. It also makes you want to learn about different ways to architect your code to make it cleaner, more reusable, and make your application easier to maintain in the long run as you go forward adding new features.

Object-oriented design (OOD) is a method of planning a system of interacting objects to solve software problems. OOD employs “hierarchical data abstraction”, where components are designed based on stable class and object roles and relations, rather than functions corresponding to actions.

It also associates actions with specific objects and/or classes of objects, which emphasize high cohesion and low coupling. And well-designed OO programs group classes and objects via patterns and combine them to form frameworks.

Creational, Structural, and Behavioural Patterns

All patterns can be categorized by their intent or purpose. A Design pattern -most of the time- fall under one of these three categories.

Creational Patterns: They are patterns that tackle how you handle creating new objects. Used to abstract the process of instantiating objects.

For example, if you are creating an object that is similar to an existing one, instead of instantiating a new object, you might clone existing objects. You might make the choice to clone, rather than instantiate based upon the language you are implementing in.

  • Languages without the notion of classes would encourage you to clone and add to existing objects.
  • Language like Javascript does not contain traditional classes to be instantiated. Objects are instead cloned and expanded to meet the purposes of those particular instances, called prototypes. Javascript allows for changes to these prototypes at run time.
  • Languages like Java and C-Sharp on the other hand, rely heavily on instantiating objects using specific classes defined at compile time.
  • The different ways of creating objects can strongly impact how you solve a problem.

Structural Patterns: They describe the relationship between objects, how objects are connected to each other, and how subclasses and classes interact through inheritance to achieve a particular design goal.

They describe how classes and objects can be combined in various ways to form larger structures.

Behavioral Patterns: These patterns focus on how objects distribute work (distribution of responsibility), the interaction and communication between objects.

They describe how each object does a single cohesive function. Behavioral patterns also focus on how independent objects work towards a common goal. Behavioral Pattern lays out the overall goal and the purpose for each of the objects.

The Goal of this Series

In this series of blog posts, we will learn together along the way different design patterns with concrete implementation examples. My goal of this series is to provide a valuable reference with an easy and reader-friendly explanation for those who want to learn about design patterns and be better programmers in general.

We are learning together, so any constructive feedback to improve how this content is presented is more than welcomed 😃.

References

[1] Design Patterns Elements of Reusable Object-Oriented Software book.