Design patterns provide tried and tested, optimum solutions to some commonly occuring problems.
Benefits of design patterns:
- Code reusability, as you might heard in object oriented programming concepts, instead of developing something over and over again from scratch, we want to reuse existing one to reduce development costs and time. Design patterns makes reusing easier.
- It makes communication easier by providing a common language on some design details.
For example an app needs a single instance of a class at runtime. if there isn't any instance created then it should be created: if there is, that one should be used instead of creating again etc.
or you could just say we need a Singleton class.
- Robust and effective solutions. As said in the first sentence design patterns are tried and tested solutions they are result of extensive experience.
- Improves code readability. It helps new or less experienced developers learn and adopt quickly.
- It helps your code to be more flexible and extensible.
Ok, we talked about some of the benefits of design patterns and want to learn more about them, so where do we start? Design patterns are divided into four category as Creational, Structural, Behavioral and Concurrency. In this writing, i am gonna try to explain some of them.
Creational Design Patterns
These kind of patterns provide various ways to create objects effective and efficient as possible.
Factory Method
Manages object creating in a flexible and maintainable way by delegating creation process to subclasses. The factory method pattern loosens the coupling code by separating our Product‘s construction from the code that uses this Product. Makes it easy to extract the Product construction independently from the rest of the application. Additionally it allows the introduction of new products without breaking existing code.
Abstract Factory
Provides an interface for creating families of related or dependent objects without specifying their concrete classes. The pattern encapsulates a group of individual factories with a common goal, and it is typically used when there are multiple families of products, and you need to provide a way to create objects from these families that can work together.
Builder
It helps you to construct a complex object step by step instead of constructing inside of its own class and making the class more complicated than it is. Allows the same construction process to create different representations of 'product'. The implementation starts with creating Builder interface/abstract class that declares steps to construct your complex Product object. Follows with Concrete Builder classes that implement Builder interface tailored to create specific variation. And finally Director which is responsible for managing contruction process of complex Product object.
Image from refactoring.guru |
Prototype
Lets you copy existing objects without making your code dependent on their classes. Hides the complexity of making new instances from the client. Allows copying an existing object rather than creating a new instance from scratch.
You may need a exact copy of an object, you may try to construct new one from the same class but what if fields are private and you cant access it from your client code. You can create prototype objects by implementing this pattern!
Singleton
This one is the most widely used design pattern. It ensures a class only has one instance, and provides a global point of access to it. Singleton classes are generally used for logging, driver objects, caching, thread pool and database connections.
When implementing a singleton class to make sure instance is unique, constructors should be private.
Structural Design Patterns
Adapter
Adapter design pattern allows objects with incompatible interfaces to collaborate.
An adapter wraps one of the objects to hide the complexity of conversion happening behind the scenes. The wrapped object isn’t even aware of the adapter. For example, you can wrap an temperature sensor object that operates in fahrenheit with an adapter that converts the sensor data to celcius.
https://github.com/cankurttekin/design-patterns-in-java/tree/main/AdapterPattern
Adapters also help objects with different interfaces collaborate. Even creating a two-way adapter that can convert the calls in both directions is possible.
Behavioral Design Patterns
Focuses on algorithms and communication between classes or objects.
Chain of Responsibility
Lets you pass requests along a chain of handlers, each handler decides either to process or to pass it to the next handler in the chain without knowing who is going to handle it. Provides freedom in handling the request.
https://www.geeksforgeeks.org/chain-responsibility-design-pattern |
You can find some of the coding examples on my GitHub repo.
https://github.com/cankurttekin/design-patterns-in-java
Resources: