Coding better using Design Patterns

Design Patterns are formalized best practices used to solve the most common problems that generally occur during OOP Software Development.

Table of Contents

Creational Patterns

They deal with object creation mechanisms (=create objects in a manner suitable to the situation).

SINGLETON — Ensures a class has only one instance and provides a global point of access to it.

Typical Use Cases (from iluwatar github repo): the logging class, managing a connection to a database, file manager. In Java it is used java.lang.Runtime.

UML Diagram

FACTORY METHOD — Creates objects without having to specify the exact class of the object that will be created.

Decouple the code that uses the type of class from the code that decides which type of class must be used.

UML Diagram

OTHERS CREATIONAL PATTERNS:

  • ABSTRACT FACTORY
  • BUILDER
  • PROTOTYPE

Structural Patterns

They deal with the creation of complex structures through the composition of classes and objects.

ADAPTER — Converts a class interface into another requested

UML Diagram

DECORATOR — Adds behavior to an object dynamically without affecting the behavior of other objects from the same class.

It is a dynamic alternative to subclassing for extending functionality, particularly when you have to extend functionality during run-time.

It is useful also if you have to add the same behaviour to many classes: using a decorator you can do it only once for all (in the following example the behaviour of “calculating the area” is added to Circle and Rectangle classes through the decorator, avoiding the creation of subclasses CircleWithDimensions and RectangleWithDimensions).

Note: Decorators — compared to Adapters, not only maps one method to another but they modify behaviour of some subject methods: adding behaviours or do not calling at all the subject method).

UML Diagram

FACADE — Provides a simplified interface to a larger body of code.

It typically involves a single wrapper class that contains a set of variables and methods required by the client that access the full body of code and hide the implementation details in order to reduce the client perceived complexity of the code.

UML example is shown instead that code one because it should be more clear.

Credits: https://en.wikipedia.org/wiki/File:Example_of_Facade_design_pattern_in_UML.png

FLYWEIGHT — Minimizes memory usage by sharing as much data as possible with other similar unchangeable objects.

Warning: This pattern may be used only with unchangeable objects. Otherwise sharing/aliasing problems are expected.

No useful example found. Readers’ contributions are appreciated ❤

PROXY — Postpone or even avoid instantiation of an heavy object using another lighter that has the same interface as its public one.

Preprocessing, caching and requests queues are used to optimize the most.

UML Diagram
Sequence Diagram

In the example above, the proxy prevent from loading every image requested until it is not explicitly requested to be displayed.

For the record: in real systems like word processors, the approach shown in the example above will speed up the opening of a document full of images, but if no “forecasting algorithms” are addedd, there will be some time-delay when is necessary displaying images (it’s an expensive&slow operation).

OTHERS STRUCTURAL PATTERNS:

  • BRIDGE
  • COMPOSITE

Behavioral Patterns

They deal with the communication between objects.

STRATEGY — Enables selecting an algorithm at runtime

Useful when a class has differents behaviors depending on input or others reasons, and you want to decouple the main code from the secondary optional codes: in this way only the needed code is actually implemented.

UML Diagram

ITERATOR — Provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

Iterators decouple the iteration algorithms from the original data structure making the code lighter and more modular, enabling also multiple concurrents iterations (one iteration, one iterator).

UML Diagram

OBSERVER — Defines a one-to-many dependance between objects (subject — listeners) in order to notify all the dependents when a change of state occurs in the subject.

Warning: this pattern cause a problem known as “Lapsed listener problem”. The solution is using weak references between subject and listeners.

UML Diagram

STATE — Creates an object with a state variable(s) on which the object’s behaviours depend. Someone says it implements a “state machine” in an object-oriented way.

Unlike the strategy pattern, the state pattern can change object’s behaviours by it self depending on the current object state and during the own execution. The strategy pattern otherwise changes the object’s behaviours once for all at creation object or methods’ calls.

UML Diagram

OTHERS BEHAVIORAL PATTERNS:

  • CHAIN OF RESPONSABILITY
  • COMMAND
  • INTERPRETER
  • MEDIATOR
  • MEMENTO
  • TEMPLATE STRATEGY
  • VISITOR

If you liked, please let me know it clapping 👏🏻 the article. Thank you 😊

Looking for official reference? Here the most famous book:

The current best reference you can refer to is Head First Design Patterns.

Looking for others patterns’ examples? Look here:


Credits:

  • Wikipedia (IT, EN)
  • Tutorialspoint.com (link)
  • “Design Patterns: Elements of Reusable Object-Oriented Softwar — Gamma, Helm, Johnson, Vlissides”.