Design Patterns mostly used

Neeru K Singh
4 min readNov 16, 2022

--

1. ) Creational

1.1) Singleton : One instance per jvm

Real life example(java) — java.lang.Runtime#getRuntime()

User A: Hey write a basic singleton class

public class SingletonExample{

private static SingletonExample singleton; // if initialize here then early loading

private SingletonExample(){
}

public static Singleton1 getInstance() {
if(singleton==null){ //lazy loading
singleton = new SingletonExample();
}
return singleton;
}
}

User A: Its not thread safe ?

User B : ok let me make method as synchronize

public class SingletonExample {

private static SingletonExample singleton; // if initialize here then early loading

private SingletonExample(){
}

public synchronized static SingletonExample getInstance() {
if(singleton==null){ //lazy loading
singleton = new SingletonExample();
}
return singleton;
}
}

User A : yeah !! Now its thread safe but there are performance issues with this approach bcoz only one thread can enter in this method to get Instance.

User B: ok let me add synchronised block(rather than method) and volatile to the instance.( double checked locking)

public class SingletonExample {

private volatile static SingletonExample singleton; // if initialize here then early loading

private SingletonExample(){
}

public SingletonExample getInstance() {
if(singleton==null){ //lazy loading
synchronized(this){
if(singleton==null)
singleton = new SingletonExample();
}

}
return singleton;
}
}

1.2) Factory method : Creates a family of object types.

Real life example (java) — java.util.Calendar#getInstance()

public interface Notification {
void notifyUser();
}
public class SMSNotification implements Notification {

@Override
public void notifyUser()
{
System.out.println("Sending an SMS notification");
}
}
public class EmailNotification implements Notification {

@Override
public void notifyUser()
{
System.out.println("Sending an e-mail notification");
}
}
//Factory method 

public class NotificationFactory {
public Notification createNotification(String channel)
{
if (channel == null || channel.isEmpty())
return null;
switch (channel) {
case "SMS":
return new SMSNotification();
case "EMAIL":
return new EmailNotification();
default:
throw new IllegalArgumentException("Unknown channel "+channel);
}
}
}

/*Below we are passing notification type- SMS so , based on that
SMSNotification object will be created in Factory method
and thier notifyUser method will be called.
*/

public class NotificationService {
public static void main(String[] args)
{
NotificationFactory notificationFactory = new NotificationFactory();
Notification notification = notificationFactory.createNotification("SMS"); //here b
notification.notifyUser();
}
}

1.3 ) Builder Pattern :

It is a creational design pattern that lets you construct complex objects step by step. It allows you to produce different types and representations of a product using the same construction code. However, this pattern should be used only if you need to build different immutable objects using the same building process.

Real life example(java) — java.lang.StringBuilder & lombok annotation @Builder to create object instance.

Below example can have different variations to write builder for any particular class.


public class Book {
private final String isbn;
private final String title;
private final String author;
private final Year published;
private final String description;

private Book(Builder builder) {
this.isbn = builder.isbn;
this.title = builder.title;
this.author = builder.author;
this.published = builder.published;
this.description = builder.description;
}

//Gettters & Setters

public static class Builder {
private final String isbn;
private final String title;
private String author;
private Year published;
private String description;

public Builder(String isbn, String title) {
this.isbn = isbn;
this.title = title;
}

public Builder author(String author) {
this.author = author;
return this;
}

public Builder published(Year published) {
this.published = published;
return this;
}

public Builder description(String description) {
this.description = description;
return this;
}

public Book build() {
return new Book(this);
}

}

}
/* Now create object by Builder pattern 
- Here isbn & Title as mandatory so passing in constuctor of Builder
and others are optional fields to create object.
*/

Book book = new Book.Builder("0-12-345678-9", "Moby-Dick")
.author("Herman Melville")
.published(Year.of(1851))
.description(
"The book is the sailor Ishmael's narrative of the obsessive quest of "
+ "Ahab, captain of the whaling ship Pequod, for revenge on Moby Dick, "
+ "the giant white sperm whale that on the ship's previous voyage bit "
+ "off Ahab's leg at the knee."
)
.build();

References :

https://dzone.com/articles/demystifying-volatile-and-synchronized-again

--

--

No responses yet