Practical Application of Design Patterns

In previous articles I have written, I emphasized one extremely important thing in programming, sticking to standards and principles. The use of SOLID, KISS and other guidelines not only help maintain order in the code itself, but also in communication between programmers.

This time around, I want to bring up a topic which 99% of employers will ask a prospective developer during a job interview. It's about design patterns.

The purpose of this article is to highlight the relationship between the use of design patterns and a set of clean code principles. In order to really apply SOLID rules effectively and conveniently, it’s important to know how to use patterns in a practical way.

However, I’m not going describe every possible design pattern, because the Internet and technical reading are already saturated with articles on this subject.

 

Let's start with a brief introduction.

 

Design patterns are universally proven solutions for recurring project’s problems. However, it should be noted that they’re a description of the solution and not the solution itself. Design patterns are applied to object oriented programming.

There are four categories of patterns:

  • creative - describes the process of creating objects.
  • behavioral (also called functional) - describes the behavior and responsibilities of cooperating objects.
  • structural - describes the structures of related objects.
  • architectural - describes more abstract patterns such as MVC.

The best known design patterns are:

  • Creative:

- Prototype

- Abstract Factory

- Factory Method

  • Structural:

- Adapter

- Facade

- Proxy

  • Behavioral:

- Strategy

- Dependency Injection

- Observer.

In this article I’m going to describe the factory design pattern and its relationship to SOLID, specifically, two types of factories: a simple factory and a factory method.

In the standard approach to object-oriented programming, each new instance of an object is created using a new keyword. Therefore, each time you create an object, you must be familiar with its specific type, and thus - know and properly fill in the constructor.

All varieties of factory are used to cut off a specific type administration. Instead, a functionality is created that returns the object instance that you’re focused on. Instead of using the new command every time, a method named e.g. CreateInstance is called.

Among the many advantages to this approach, is that it almost always falls in line with two SOLID principles - Dependency inversion and Open for expansion, closed for modification (Open / closed).

Why these two and why almost always? I will explain a bit below.

A simple factory is the most commonly type of factory used, typically by novice programmers, and works very well in most straight forward cases. Imagine a situation where you have to create an object relating to an animal species. All code fragments presented are written in PHP.

In a traditional approach, the code would look like this:

 

 

However, using the simple factory pattern, we get the following code:

 

The code is very simple, creating individual instances has been closed in the factory class. However, in this simple example, you can see the application of the Dependency inversion principle mentioned earlier. We’ve made the code of the main part of the application independent of a specific type of figure, using abstraction in the form of a Shape interface. The disadvantage of this solution is, however, breaking the second SOLID rule, Open / Closed. When you add a new geometric figure class, you’ll need to modify the ShapeTypeEnum and ShapeFactory classes.

 

The second type of factory is the factory method. Referencing the same situation as before, using this type of pattern, the code will look like this:

 

In the above code, the factory main class is an abstract class. The earlier switch has been replaced by a polymorphism mechanism.

Responsibility for creating specific objects was "dumped" on the factory’s child classes. Thanks to this solution, adding a new animal class does not force the programmer to modify any of the earlier created classes, and thus the Open / Closed Principle is not broken.

The above examples are quite simple and the scenarios are somewhat exaggerated, but are intended to show the idea of the factory, which, when approached in conjunction with SOLID, allows you to write  clean optimal code that complies with industry standards.

Krzysztof Chadynka Backend Developer