I fell in love with Java programming after learning the software design patterns and Spring Boot framework. The Gang of Four(GoF) formulated 23 software design patterns. The software design patterns are the reusable solutions to the most frequently occurring problems in the software design. It is not a fixed set of algorithms that you can use. Rather, it provides a template/approach for solving a particular design problem. Each pattern within the 23 design patterns solves a specific design problem.
Categories of 23 Software Design Patterns
The 23 GoF patterns are categorized into three. They are creational, structural, and behavioral categories. The picture below separates each 23 patterns into specific categories.
The creational category patterns deal with the creation of objects. The structural category deals with the composition of objects into bigger structures. Finally, the behavioral category deals with the interaction among the various objects in the software system. All the patterns contribute towards designing a modular system that is easy to maintain and extend without modifying the existing system. If at all with the minimum amount of modification.
Four Essential Elements of Design Patterns
In general, the pattern will have four essential elements. They are as follows
Describing Design Pattern
When describing each design pattern the most common terms that you come across are
The other terms you might come across are Also Known As, Participants, Collaborations, Known Uses, Related Patterns, etc… The participants are the components(classes and interfaces) of the structure.
Example: Observer pattern also known as publish-subscribe pattern
Let’s look into the Observer pattern and see what it does. What problem does it solve in the software design? How to implement it? We will use Java programming to implement it.
Intent
It models the publisher and subscriber communication. The subscribers are notified whenever the publisher publishes new content. It simulates the one-to-many dependency between the objects. The subscribers are dependent on the state of the publisher.
Structure
Implementation
Let’s implement the Observer pattern for a news publishing company. There will be subscribers to the news company which is considered Observer. The news publishing company itself is the subject to which the Observer keeps an eye on. Whenever the news is published, all the subscribers are notified immediately of the news.
This is the helper class with which we can create news. It will be the collection of the articles.
import java.util.List;
import java.util.ArrayList;
//Article
public record Article(String name, String body) {}
//News
public class News{
List<Article> newsArticles = new ArrayList<>();
public void addArticle(Article article){
newsArticles.add(article);
}
public List<Article> getArticles(){
return newsArticles;
}
}
This is the Observer interface. It keeps an eye on the publisher.
//Observer Interface
public interface User{
public void update(News news);
public String getId();
}
This is the concrete implementation of the Observer. Whenever there is an update in the news, it calls the readNews() method to display all the articles inside the news.
//Concrete Observer
public class NewsLetterUser implements User{
private String name;
private String userId;
private News news;
public NewsLetterUser(String name, String userId){
this.name = name;
this.userId = userId;
}
public void update(News news){
this.news = news;
readNews();
}
public String getId(){
return userId;
}
public void readNews(){
System.out.println("User: " + name);
System.out.println("Reading the Kunsel News");
for(Article article: news.getArticles()){
System.out.println("\t" + article);
}
}
}
This is the real subject interface. It will have the methods to subscribe, unsubscribe, notifySubscriber, and publish news.
//Subject Interface
public interface NewsLetter{
public void subscribe(User user);
public void unSubscribe(User user);
public void notifySubscriber();
public void publish(News news);
}
This is the concrete implementation of the real subject. The Observers are interested in the change of the News object state. Whenever there is a new object of News, all the Observers will be notified of the new News object content. Kuensel is the news publisher.
import java.util.HashMap;
//Concrete Subject
class Kuensel implements NewsLetter{
private HashMap<String, User> subscribers = new HashMap<>();
private News news;
public void subscribe(User user){
subscribers.put(user.getId(), user);
}
public void unSubscribe(User user){
subscribers.remove(user.getId());
}
public void notifySubscriber(){
for(HashMap.Entry<String, User> user: subscribers.entrySet()){
user.getValue().update(news);
}
}
public void publish(News news){
this.news = news;
notifySubscriber();
}
}
This is the Client, which interacts with the Observer pattern.
//Client
public class NewsLetterApp {
public static void main(String[] args){
//Lets build the Kunsel News First
News kuenselNews = new News();
kuenselNews.addArticle(new Article("Rising Temperature", "The global warming is causing the rise in the temperature"));
kuenselNews.addArticle(new Article("Forest Fire", "The forest fire broke out in the capital"));
//Real Subject
Kuensel kuensel = new Kuensel();
kuensel.subscribe(new NewsLetterUser("Sonam", "sonam123"));
kuensel.subscribe(new NewsLetterUser("John", "john123"));
//Lets publish the news
kuensel.publish(kuenselNews); //Should see all the user in the console with the news
kuensel.unSubscribe(new NewsLetterUser("John", "john123"));
kuensel.publish(kuenselNews); // Publish same news, only Sonam should see the news
}
}
Except for the News.java class, all the other classes represent the participants of the Observer pattern. In other words the components of the structure of the Observer pattern.
Output
User: Sonam
Reading the Kunsel News
Article[name=Rising Temperature, body=The global warming is causing the rise in the temperature]
Article[name=Forest Fire, body=The forest fire broke out in the capital]
User: John
Reading the Kunsel News
Article[name=Rising Temperature, body=The global warming is causing the rise in the temperature]
Article[name=Forest Fire, body=The forest fire broke out in the capital]
User: Sonam
Reading the Kunsel News
Article[name=Rising Temperature, body=The global warming is causing the rise in the temperature]
Article[name=Forest Fire, body=The forest fire broke out in the capital]
Consequences
Some of the consequences of applying the observer pattern are
Conclusion
There is no hard rule stating when to use these 23 patterns of Gang of Four. It is up to the developer or the architect of the software system to decide. If you use it, definitely it gives you the power to write clean code. Which is modular and easy to maintain. Also, it can be very flexible to extend and reuse the code in the software system. When developing frameworks it is used most but not limited to it only. The Java Spring Boot framework uses lots of these patterns. After learning all the patterns you will find the Spring Boot framework easy to understand how it works under the hood.
I am an enthusiastic tech guy. Ever ready to learn new technology. I love building software solutions that can help mankind to solve problems.
You can support us by:
Becoming a patron at https://www.patreon.com/drukinfotech
Buy me coffee at https://www.buymeacoffee.com/drukinfotech
Your writing has a way of making even the most complex topics accessible and engaging. I’m constantly impressed by your ability to distill complicated concepts into easy-to-understand language.