23 Design Patterns 99% of Java Developers Should Learn
Mastering Essential Design Patterns for Java Development Success
Hello guys, if you want to learn Design Patterns and looking for a comprehensive tutorial which covers all important object oriented design pattern then you have come to the right place. Earlier, I have shared best Design pattern courses and books for experienced developers and in this article, I will introduce you with 23 common object oriented design patterns for writing better code.
Design Patterns are tried and tested way of solving a problem within a given context. They are not invented, rather they are discovered, which is also obvious by use of word pattern. By using design pattern, you take knowledge of all wide communities and can safely use it to solve that problem.
At times they might not give you perfect solution, require bit of tweaking, but they certainly provides one of the best solution, as long as you use them properly. While doing object oriented development, they are numerous task which appears quite often e.g. creating objects, structuring code, and implementing different behaviors based on different context.
Along the same line GOF recognized and divided design patterns in Creational, Structural and Behavioral patterns, in there classic book Design patterns.
Though there are many more patterns which are used at different domain and across different projects, this catalog and book becomes a primary source to learn design pattern. To be frank, understanding design pattern is difficult job and applying them in your project is even more difficult.
Though I have found that, having a knowledge of different pattern in the back of your mind, helps to identify scenarios when pattern surfaces. If you have not spend much time with different design pattern than I suggest to get yourself a copy of Head First Design patterns by Kathy Siera, Freeman, Robson and Bates and the Design pattern explained by Shalloway and Trott.
I personally prefer head first book because of interactive discussion they provide, there fireside chats, UML diagrams and cubical conversation helps tremendously to understand a design pattern, pros and cons and most importantly applicability.
Unfortunately that book doesn’t cover all the design patterns mentioned by Gang of Four, so a second book is also necessary. Identifying patterns in different projects, frameworks and libraries is also a great way to learn design patterns in Java. For example, JDK itself uses several design patterns and serves a good reference for beginners.
Though, if you want to learn design pattern in depth and looking for resources, I would recommend checking out Design Patterns in Java course by Dmitri Nestruk on Udemy. It’s a great course to learn Design pattern in depth and examples are also give in Java.
23 Essential Object-Oriented Design Patterns for Java Programmers
Now, its time to explore all the object oriented pattern divided into 3 types, creational, structural and behavioral, one by one:
1. Creational Design Patterns in Java
If you don’t know Creational design patterns in Java are a group of design patterns that focus on object creation mechanisms. They aim to encapsulate the object instantiation process, making it more flexible and less tightly coupled with the client code.
These patterns include Singleton, which ensures only one instance of a class exists; Factory Method, which allows subclasses to create objects; Abstract Factory, providing a family of related objects; Builder, for step-by-step construction of complex objects; and Prototype, allowing object cloning.
Creational patterns promote code reuse, maintainability, and scalability, facilitating the creation of objects in a controlled and efficient manner to meet diverse application requirements.
Here is a list of popular Creational Design Pattern in Java.
1. Factory Design pattern in Java
The Factory pattern is a very useful and recognized pattern to create instance of objects in Java. It provides better control over object creation process then constructor. If you want to see an example of Factory pattern, you can see my earlier post about how to implement Factory pattern in Java.
2. Abstract Factory Design pattern in Java
Abstract Factory pattern is extension of previous design pattern. It adds another layer of abstraction over Factory design pattern. In this case, Factory itself is abstract, which allows programs to choose different factory implementation, which produce different flavor of same product depending upon localization, and other requirements. You can see difference between factory and abstract factory pattern to learn more about it.
3. Builder Design Pattern
This pattern help you to create instance of complex object, which requires too many parameters. Once you exceed unwritten rule of more than five parameters for constructor, you will find yourself very hard to create instance.
Since most of the parameters are also optional, it make no sense to just provide null or false for them. Builder sort this mess, it gives you clean and fluent interface to specify what you need and return product based upon those parameters.
For code example, you can see my earlier Builder design pattern tutorial where I have talked more about this pattern.
4. Singleton Design Pattern in Java
Singleton is a useful pattern, which provides an easy way to access global objects in an application. Costly objects like Repository, Cache are almost always a Singleton in an application. Singleton pattern provides a consistent way to use them.
If you are wondering how to implement Singleton pattern in Java then you can also checkout my 5 ways to implement Singleton Pattern in Java.
By the way, with advent of test driven programming, Singleton has now become an anti pattern because of its inflexibility to provide test doubles during unit testing. Singleton are like static methods, which is very hard to mimic, a key requirement of test driven development.
5. Prototype Design Pattern in Java
Don’t know much about Prototype pattern but whatever I know, I remember that it delegates the cloning process to the actual objects that are being cloned.
It’s also visible from following diagram where you can see Image is a common interface and has clone method but actually cloning is done by ImageOne
and ImageTwo
prefer not to clone anything.
These were the Creational patterns from the original Gang of Four pattern list. They help you to solve problem related to creating objects.
2. Structural Design Patterns in Java
Structural design patterns in Java are a set of design patterns that focus on organizing and composing classes and objects to form larger structures. These patterns aim to enhance code flexibility, reusability, and maintainability by promoting class and object collaboration.
The patterns include Adapter, which allows incompatible interfaces to work together; Bridge, decoupling abstraction from implementation; Composite, treating objects and compositions uniformly; Decorator, adding functionality to objects dynamically; Facade, providing a unified interface to a complex subsystem; Flyweight, conserving memory by sharing objects; and Proxy, controlling access to objects.
Structural patterns help build well-structured, extensible, and modular Java applications.
Here is list of major Structural design patterns in Java.
6. Decorator Design Pattern in Java
Decorator pattern is used to add additional functionality on Object at runtime. It doesn’t alter the interface, just adds new functionalities using Composition.
7. Adapter Design Pattern in Java
Adapter pattern is used to convert interfaces, so that two parties can work together, which otherwise can not because of incompatible interfaces. One example of Adapter pattern is
8. Composite Design Pattern in Java
Composite design pattern allows a client to treat collections of objects and individual objects uniformly. One way to identify Composite pattern is a tree like structure.
In a tree, a node can either be a leaf node or another tree, similarly in Composite design pattern we have individual object and Composites. Though, operation on leaf and composite behave differently, but they are transparent to client.
For example in an Organization tree, some employees are manager and has set of employees reporting to them. If we have a method called directs() which returns employees under a Manager, a normal employee may return empty list, while an Employee who is manager will return a list of Employees.
9. Facade Design Pattern in Java
Sole job of Facade pattern is to make an interface simpler for use. It is used to simplify interface of one or more classes, so that they are easier to use.
10. Proxy Design Pattern in Java
Proxy design pattern allows you to control access of an object due to various reason e.g. Security, Performance, Caching etc. Proxy implements same interface as real object, so it can act as surrogate, until real object is available and than it can forward request to real object for processing.
11. Flyweight Design Pattern
The Flyweight design pattern in Java is a structural pattern that focuses on efficient memory usage by sharing intrinsic, non-changing state among multiple objects. It achieves this by separating the intrinsic state from the extrinsic state of an object.
The intrinsic state is shared and managed centrally, while the extrinsic state is unique to each object and can be passed as needed. This pattern is particularly useful when there are a large number of similar objects that can be consolidated to save memory.
By reducing memory overhead, the Flyweight pattern enhances performance, especially in resource-intensive applications, and allows the creation of a large number of objects without consuming excessive memory.
The Flyweight pattern is also extensively used in JDK e.g. Integer.valueOf()
or String.valueOf()
methods are example of Flyweight pattern in Java.
12. Bridge Design Pattern
The Bridge design pattern in Java is a structural pattern that decouples an abstraction from its implementation, allowing them to vary independently. It achieves this by creating two separate hierarchies: the Abstraction hierarchy, representing high-level functionality, and the Implementation hierarchy, representing low-level implementation details.
The Bridge pattern promotes flexibility and extensibility, enabling new abstractions and implementations to be added independently without modifying existing code. This pattern is particularly useful when there are multiple dimensions of variation in a system.
It facilitates better code organization, enhances code reusability, and simplifies the maintenance of complex systems by providing a clear separation between abstractions and their implementations.
The bridge design pattern is also used to solve X problem in Java application. By using this pattern you can reduce complexity of your solution.
3. Behavioural Design Patterns in Java
Behavioral design patterns in Java are a group of design patterns that focus on defining the communication and interaction between objects and classes. These patterns promote flexibility, reusability, and maintainability by encapsulating various behaviors within separate objects.
Some common behavioral patterns in Java include the Observer pattern, facilitating one-to-many dependency relationships; Command, encapsulating requests or operations as objects; Strategy, enabling interchangeable algorithms or behaviors; Template Method, defining the skeleton of an algorithm and allowing subclasses to implement specific steps; Iterator, providing a standard way to traverse collections; and Mediator, centralizing communication between objects.
Behavioral patterns enhance the overall organization and collaboration of Java applications, making them more scalable and adaptable to changing requirements.
This list contains some of the very useful behavioral design patterns for Java programmers.
13. Strategy Design Pattern in Java (example)
Strategy Pattern encapsulate interchangeable behaviors, known as Strategy or algorithm and uses delegation to decide, which behavior to use at run time. This pattern is based upon Open Closed design principle which promote how to write extensible code without touching already tried and tested code.
14. State Design Pattern in Java (example)
State Pattern allows an object to change its behavior, when some state changes. It’s one of the popular design pattern and you can use State Pattern to solve many interesting problem.
For example, you can use State design pattern to implement state machine as well. Earlier, I have also showed you how to implement Vending Machine using State Pattern in Java, which is another great example of how and when to use State pattern in Java.
15. Command Design Pattern in Java (example)
Command design pattern allows you to decouple the requester of an action from the object that actually performs the action. This is achieved by introducing a command object, an interface with a predefined method. Command object encapsulate actual object which performs the action.
Requester only knows about Command object and doesn’t know specifics of actual object, which reduce coupling between requester and action object.
All requester needs to know is call method on command object, which then delegates the request to specific action object. For example, Command pattern is a behavioral pattern as defined by seminal book Design Patterns by GOF.
16. Template Design Pattern in Java (Example)
Template pattern is used to define an algorithm, but deferring certain steps to subclasses. By encapsulating Algorithm in super class, this pattern don’t allow modification of algorithm, but provides flexibility by letting sub class to implement certain steps. In short, Template Pattern allows subclass to decide how to implement steps in an algorithm.
17. Observer Design Pattern in Java (example)
Observer pattern is used to notify a set of objects, when state of a another object changes. Object, whose state change is notified is called Subject or Observable, because it’s observed by a set of Objects, known as Observer.
If you are wondering how to implement Observer pattern in Java then you can see my Java Observer Design pattern tutorial, there I have shared complete code example from real world, just follow along.
18. Iterator design Pattern in Java (example)
The Iterator design pattern in Java is a behavioral pattern that provides a standardized way to traverse elements in a collection without exposing its underlying representation. It allows sequential access to elements using a common interface, decoupling the iteration logic from the collection implementation.
The Iterator interface defines methods like hasNext()
to check for the next element's existence and next()
to retrieve it. Java's built-in collections, like ArrayList and LinkedList, implement their specific Iterator, enabling efficient and consistent element retrieval.
This pattern promotes code reusability, simplifies collection traversal, and enhances maintainability by isolating iteration concerns from the collection's core functionality.
In short, Iterator pattern provides a way to traverse a collection or aggregation of object without exposing internal details of Collection.
19. Visitor Design Pattern in Java
Visitor is another useful object oriented design pattern which is based upon concept of double dispatch. It removes ugly chain of if-else code require to customize behavior of different objects in same class hierarchy. It also follows open close design principle of SOLID principle. It stands for “O” in SOLID.
20. Chain of Responsibility Pattern
The Chain of Responsibility pattern is a behavioral design pattern in Java that promotes loose coupling and helps build a chain of processing objects. Each object in the chain has a single responsibility and is linked together to process a request in sequence.
When a request is made, it is passed along the chain until a handler capable of processing it is found. This pattern avoids hardcoding the receiver of a request, allowing multiple handlers to have a chance to handle it.
It enhances flexibility, reusability, and scalability by dynamically altering the chain’s structure or adding new handlers without modifying the client code.
21. Interpreter Design Pattern
The Interpreter design pattern in Java is a behavioral pattern that facilitates the creation of a language interpreter. It enables the interpretation of a given language or expression by defining its grammar and providing an interpreter to evaluate and execute the expressions.
The pattern consists of classes representing grammar rules and terminal symbols, while the interpreter evaluates non-terminal symbols recursively to produce results. It’s well-suited for scenarios involving complex languages or rule-based systems where processing expressions step-by-step is necessary.
The Interpreter pattern promotes extensibility and maintainability by separating language-specific logic from the rest of the application, making it easier to introduce new language features or variations.
22. Mediator Design Pattern
The Mediator design pattern in Java is a behavioral pattern that facilitates communication between multiple objects without direct dependencies. It promotes loose coupling by introducing a mediator that acts as a central communication hub.
Instead of objects communicating with each other directly, they interact only with the mediator, which relays messages to the appropriate recipients.
This decoupling enhances flexibility, as components can change or evolve independently. The Mediator pattern is particularly useful in complex systems where many objects interact, preventing a network of tightly coupled relationships.
It simplifies the overall design, eases maintenance, and enhances the overall organization of interactions between objects.
23. Memento Design Pattern
The Memento design pattern in Java is a behavioral pattern that enables the capture and restoration of an object’s internal state. It achieves this by encapsulating the object’s state into a separate Memento object, which is then stored by a Caretaker object.
The originator object can create and restore states using Memento objects, allowing it to undo or rollback to previous states easily. This pattern promotes data encapsulation and maintains the object’s integrity, as the state remains hidden from external access.
The Memento pattern is particularly useful in scenarios where undo/redo functionality or historical records of an object’s state are required.
And, here is the big diagram which shows the relationship between different object oriented design patterns:
That’s all on this list of essential object oriented design patterns an experienced and senior Java developers should know. This patterns are not restricted to Java programming language and can be used with any other object oriented programming language like Python, C++, or TypeScript.
While this is a long article, you can bookmark it and refer it again and again to get familiar with these patterns. I also plan to keep updating this article and adding more useful info in future.
Other Java Design Patterns tutorials you may like
- How to design a Vending Machine in Java? (questions)
- 5 Free Courses to learn Object Oriented Programming (courses)
- How to implement a Decorator design pattern in Java? (tutorial)
- When to use Command Design Pattern in Java (example)
- How to use Factory method design pattern in Java? (tutorial)
- 7 Best Courses to learn Design Pattern in Java (courses)
- How to implement the Strategy Design Pattern in Java? (example)
- Difference between Factory and Abstract Factory Pattern? (example)
- How to create thread-safe Singleton in Java (example)
- 7 Best Books to learn the Design Pattern in Java? (books)
- Difference between Factory and Dependency Injection Pattern? (answer)
- Difference between State and Strategy Design Pattern in Java? (answer)
- 18 Java Design Pattern Interview Questions with Answers (list)
- 20 System Design Interview Questions (list)
- 5 Free Courses to learn Data Structure and Algorithms (courses)
- 10 OOP Design Principle Every Java developer should learn (solid principle)
- 7 Books to learn System Design for Beginners (System design books)
- How to use Composite Design Pattern in Java (composite example)
Thanks a lot for reading this article so far. If you like these essential design pattern in Java and find this article worth your time then please share it with your friends and colleagues. If you have any questions or feedback then please drop a note.
P. S. — If you are an experienced Java developer and want to learn Design patterns and looking for a best design pattern resources like books and online courses then you can also check out this list of best design pattern courses for experience developers to start with. It contains online courses to learn design pattern and how to use them in real world coding. And, if you want to learn Microservices patterns, I have also shared it here.