BLOG

Design Patterns

Design patterns are proven solutions to common programming problems that are universal and can be applied across various programming languages. They describe structures and principles for organizing code that help create more readable, maintainable, and scalable applications. Design patterns are divided into different categories, such as behavioral (e.g., Observer, Strategy), creational (e.g., Singleton, Factory), and structural (e.g., Adapter, Decorator).

Behavioral pattern

OBSERVER

The main purpose of this pattern is to communicate changes in the state of an object. It is built with two interfaces: Observer and Observable. The Observer is an object that monitors a specific object and responds accordingly to any changes that occur in it. The Observable is an object that is observed by multiple observers. The Observable interface should have three methods that allow it to: add a new observer, remove an existing observer, and notify observers of a change.

EXAMPLE – There are three observers (a professor, a doctor, and a student) monitoring the oxidation reaction of a glucose solution. They take notes on the progress of this reaction by observing when a color change occurs (first, the solution is blue, then green, red, and finally yellow). They observe the reaction at different times and need to inform each other if a change has already occurred.

Creational pattern

FACTORY

The main purpose of this pattern is to simplify the creation of new objects. This pattern creates a layer of abstraction responsible for instantiating objects that are related through a common interface. It has two very important elements: encapsulation of new objects (which hides the implementation of creating new objects) and abstraction. It exists in three variants: simple factory, factory method, and abstract factory. The simple factory returns an object that implements one interface, without any inheritance or composition mechanisms present. It is difficult to extend. The factory method also returns an object that implements one interface and does not contain composition, but it always includes an inheritance mechanism. Due to the presence of the inheritance mechanism and polymorphism, this method is easy to extend. The abstract factory always includes both inheritance and composition mechanisms. It is called a factory of factories because, by using the composition mechanism, it returns factory methods.

EXAMPLE – In a chemical company, there is a need to build laboratories: an organic lab and an inorganic lab. To do this, we first create an abstract factory that then implements the creation of a specific factory: LabFactory. This factory will create a specific object, either OrganicLab or InorganicLab, depending on the type of laboratory. By using the factory method, we can easily create additional laboratories if needed (e.g., a physics lab or a biology lab).

Structural pattern

DECORATOR

This pattern is used for dynamically extending the responsibilities of a given class. It consists of four components: an abstract class (Component), a concrete implementation of the abstract class, an abstract class that enriches the object (Decorator), and a concrete implementation of the enriching class.

EXAMPLE – In a laboratory, we need to have different chromatographs (specialized devices for analyzing samples). Each chromatograph consists of fixed elements, such as an injector, a column, and a UV lamp, but depending on the type, we can decorate it with additional elements. For example, a SEC chromatograph may have an autosampler or an additional lamp.