Design Patterns


A design pattern systematically names, motivates, and explains a general design that addresses a recurring design problem in object-oriented systems.

A design patterns are well-proved solution for solving the specific problem/task.

Use the design patterns during the analysis and requirement phase of SDLC.

A design pattern provides a general reusable solution for the common problems that occur in software design.

The idea is to speed up the development process by providing well-tested, proven development/design paradigms.

The pattern typically shows relationships and interactions between classes or objects.

By using design patterns, make code more flexible, reusable, and maintainable.

Design patterns are categorized into two parts:
I. Core Java (or JSE) Design Patterns.
II. JEE Design Patterns

Core Java Design Patterns
There are 23 design patterns which can be classified in three categories.

1) Creational patterns - provide a way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator.
1. Factory Method
2. Abstract Factory 
3. Builder
  Builder is a creational design pattern that lets you construct complex objects step by step. 
  The pattern allows you to produce different types and representations of an object using the same construction code.
4. Singleton 
5. Object Pool
6. Prototype

2) Structural patterns - concern class and object composition.
1. Adapter Pattern
2. Bridge Pattern
3. Composite Pattern
4. Decorator Pattern
5. Facade Pattern
6. Flyweight Pattern
7. Proxy Pattern

3) Behavioral patterns - are specifically concerned with communication between objects.
1. Chain Of Responsibility Pattern
2. Command Pattern
3. Interpreter Pattern
4. Iterator Pattern
5. Mediator Pattern
6. Memento Pattern
7. Observer Pattern
8. State Pattern
9. Strategy Pattern
10. Template Pattern
11. Visitor Pattern

Factory Method Pattern
A Factory Pattern or Factory Method Pattern says that just define an interface or abstract class for creating an object but let the subclasses decide which class to instantiate.
In other words, subclasses are responsible to create the instance of the class.
The Factory Method Pattern is also known as Virtual Constructor.
It promotes the loose-coupling.

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");
}
}
public class PushNotification implements Notification {
@Override
public void notifyUser() {
System.out.println("Sending a push notification");
}
}
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();
case "PUSH":
return new PushNotification();
default:
throw new IllegalArgumentException("Unknown channel "+channel);
}
}
}
public class NotificationService {
public static void main(String[] args) {
NotificationFactory notificationFactory = new NotificationFactory();
Notification notification = notificationFactory.createNotification("SMS");
notification.notifyUser();
}
}


How to prevent Singleton Pattern from Reflection, Serialization and Cloning?
Reflection: Reflection can be caused to destroy singleton property of the singleton class.
Overcome reflection issue: To overcome issues raised by reflection, enums are used because java ensures internally that the enum value is instantiated only once. Since java Enums are globally accessible, they can be used for singletons. Its only drawback is that it is not flexible i.e it does not allow lazy initialization.

Serialization:- Serialization can also cause breakage of singleton property of singleton classes.
Overcome serialization issue:- To overcome this issue, we have to implement the method readResolve() method.

Cloning: Cloning is the concept to create duplicate objects. 
Overcome Cloning issue: To overcome this issue, override clone() method and throw an exception from clone method that is CloneNotSupportedException.

class Singleton {
    // public instance initialized when loading the class
    public static Singleton instance = new Singleton();
    private Singleton() {}
}
public class GFG {
    public static void main(String[] args) {
        Singleton instance1 = Singleton.instance;
        Singleton instance2 = null;
        try {
            Constructor[] constructors = Singleton.class.getDeclaredConstructors();
            for (Constructor constructor : constructors) {
                // Below code will destroy the singleton pattern
                constructor.setAccessible(true);
                instance2 = (Singleton)constructor.newInstance();
                break;
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("instance1.hashCode():- " + instance1.hashCode());
        System.out.println("instance2.hashCode():- " + instance2.hashCode());
    }
}

// Java program for Enum type singleton
public enum Singleton {
INSTANCE;
}

Comments

Popular posts from this blog

PL/SQL

JAVA8 Features

Build Automation