Design Patterns in Java

In this post, we will take a look into what design patterns are, the categories of design patterns, and the implementation of all the GOF design patterns in Java with examples.

What are Design Patterns?

In software engineering, a design pattern is a general repeatable solution to a commonly occurring problem in software design. A design pattern isn't a finished design that can be transformed directly into code. It is a description or template for how to solve a problem that can be used in many different situations.

Uses of Design Patterns

  • Design patterns can speed up the development process by providing tested, proven development paradigms. 
  • Often, people only understand how to apply certain software design techniques to certain problems. These techniques are difficult to apply to a broader range of problems. Design patterns provide general solutions, documented in a format that doesn't require specifics tied to a particular problem.
  • In addition, patterns allow developers to communicate using well-known, well-understood names for software interactions. Common design patterns can be improved over time, making them more robust than ad-hoc designs.

Object-oriented design principles

Before reading design patterns, I suggest reading some useful oops design principles:
  • Encapsulate what varies.
  • Code to an interface rather than to an implementation
  • Delegation principle
  • The open-closed principle (OCP)
  • DRY- Don't Repeat Yourself 
  • Single Responsibility Principle (SRP)
  • Liskov Substitution Principle (LSP)
  • Interface Segregation Principle (ISP)
  • Dependency Injection or Inversion principle
Read more detail about object-oriented design principles in my post at Object-oriented design principles

Organizing the Catalog

Design patterns are organized into Creational, Structural, or Behavioral purposes.
  • Creational patterns concern the process of object creation. 
  • Structural patterns deal with the composition of classes or objects. 
  • Behavioral patterns characterize how classes or objects interact and distribute responsibility. 

1. Creational Patterns

In software engineering, creational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic form of object creation could result in design problems or added complexity to the design. Creational design patterns solve this problem by somehow controlling this object creation.
  • Factory Design Pattern - Define an interface for creating an instance of a class, with its subclasses deciding which class to instantiate.
  • Abstract Factory Design Pattern - Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
  • Builder Design Pattern - Separate the construction of a complex object from its representation, allowing the same construction process to create different representations.
  • Prototype Design Pattern - Specify the kinds of objects to create using a prototypical instance and create new objects by copying this prototype.
  • Object Pool Design Pattern - The Object Pool Design Pattern provides a mechanism to reuse objects that are expensive to create.

2. Structural Patterns

In Software Engineering, Structural Design Patterns are Design Patterns that ease the design by identifying a simple way to realize relationships between entities.
  • Adapter Design Pattern - Convert the interface of a class into another interface that clients expect, allowing classes to work together that couldn't otherwise due to incompatible interfaces.
  • Bridge Design Pattern - Decouple an abstraction from its implementation, allowing both to vary independently.
  • Composite Design Pattern - Compose objects into tree structures to represent part-whole hierarchies, enabling clients to treat individual objects and compositions uniformly.
  • Decorator Design Pattern - Attach additional responsibilities to an object dynamically, offering a flexible alternative to subclassing for extending functionality.
  • Facade Design Pattern - Provide a unified interface to a set of interfaces in a subsystem, defining a higher-level interface that makes the subsystem easier to use.
  • Proxy Design Pattern - Provide a surrogate or placeholder for another object to control access to it.

3. Behavioral Patterns

In software engineering, behavioral design patterns are design patterns that identify common communication patterns between objects and realize these patterns. By doing so, these patterns increase flexibility in carrying out this communication.
  • Chain of responsibility - Allow an object to pass the request along a chain of potential handlers until an object handles it or the end of the chain is reached.
  • Command Design Pattern - Encapsulate a request as an object, thereby allowing for parameterization of clients with different requests, queuing of requests, and logging of operations.
  • Interpreter Design Pattern in Java - Provide a representation for a language's grammar and an interpreter to execute the derived representation.
  • Iterator Design Pattern - Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
  • Mediator Design Pattern - Define an object that encapsulates how a set of objects interact, promoting loose coupling by preventing objects from referring to each other explicitly.
  • Memento Design Pattern - Capture and externalize an object's internal state without violating encapsulation, so the object can be restored to this state later.
  • Observer Design Pattern - Define a one-to-many dependency between objects so that when one object changes state,
  • State Design Pattern - Allow an object to alter its behavior when its internal state changes, appearing as if the object changed its class.
  • Strategy Design Pattern - Define a family of algorithms, encapsulate each one, and make them interchangeable, allowing the algorithm to vary independently from the clients that use it.
  • Template Method Design Pattern - Define the skeleton of an algorithm in an operation, deferring some steps to subclasses, and letting subclasses redefine certain steps of an algorithm without changing its structure.
  • Visitor Design Pattern in Java - Represent an operation to be performed on elements of an object structure, allowing the addition of new operations without modifying the classes of the elements on which they operate.
These patterns provide reusable solutions to common software design problems. It's important to remember that design patterns are not prescriptive solutions but rather general approaches that can be adapted to specific situations.