Design Patterns in Java

There are 23 design patterns which can be classified into 3 categories  :

1] Creational Patterns

The creational patterns aim to separate a system from how its objects are created, composed, and represented. They increase the system's flexibility in terms of the what, who, how, and when of object creation.

2] Structural Patterns

Structural  patterns are concerned with how classes and objects can be composed, to form larger structures. The structural design patterns simplifies the structure by identifying the relationships. These patterns focus on, how the classes inherit from each other and how they are composed from other classes.

3] Behavioral patterns

Behavioral Patterns are concerned with the interaction and responsibility of objects.In these design patterns,the interaction between the objects should be in such a way that they can easily talk to each other and still should be loosely coupled.




👷‍♂️ 18 Design Patterns : 

 Strategy
 Factory Method
 Observer
 Builder
 Adapter
 Decoretor 
 Bridge
 Singleton
 Command
 Façade
 Proxy
 Null object pattern
 Template method
 Composite
 Prototype
 State
 Abstract Factory
 Chain of Responsibility

 

 Dependency injections



-----------------------------------------------------



SINGLETON PATTERN ( Creational Pattern ) :

useful Video : https://youtu.be/VGLjQuEQgkI 
blogs on Java Syncronisation: 

Test.java : 
public class Test  {

//Make Constructor Private so that no one
//can create a new Instance outside this Class
private Test() { }

//Create Instance Variable for that single Instance.
private static Test testObject = null;

//Create a a public method to return the Instance.
//Make it syncronised depending on your need to be Thread-Safe.
public synchronized static Test getInstance(){

if (testObject==null){
testObject=new Test();
}
return testObject;
}

public static void main(String[] agrs){ }

A Singleton pattern is Applied only to a class which needs to create only and ONLY ONE  Instance or object in the Entire Code.


Step1 ] Make the Constructor private 

Step 2] Make a Single Instance variable of that class and make it null. We'll later initialise the Class object on this variable and return it.

Step 3] Create a Static method , getInstance() is a Industry standard .

Check if our Instance Variable is null or not , if it is null then it means that its getting called for the first time.

If it is null , then Initiate our Instance Variable and return it.

(Make the Method Syncronised too to be Thread safe)

Thats it ! Now you can Call the Method can get the Object .

SINGLETON PATTERN IS NOT APPRECIATED MUCH , since we always need to Add or Change code and creating just a single object limits future scaling and features. Yet in some situations we do need this Pattern.


------------------------------------------------------------


FACTORY  PATTERN ( Creational Pattern ) :

Useful video : https://youtu.be/jcGSowIzmzM

Factory pattern is used when we have alott of Subclasses inside the Super class.
Without Factory method we'll have to use "new Object name" everytime we want to call a new subclass.
With Factory method we create a static method and whenever we need a sublcass , all we have to do is call this Static method and pass it the Class name and it'll return us a new object of that subclass.



Step 1] Create  a Factory class , Inside which we'll create the Static method for returning subclasses.

Step 2] Inside the class create a Static method and make it return the Superclass.

You can take any number of Parameters inside this method as per your Subclasses, but ONE parameter whihc is Very Very important is the subclass name the user wants the method to return.

Step 3] Once we have the subclass name , apply conditions and return appropriate subclass objects.



Test.java :

public class Test  {

public static void main(String[] agrs){

Vehicle Apollo = VehicleFactoy.getObject("ApolloIE");
Apollo.Horn();

}
}

//Create a Static factory class
class VehicleFactoy {

public static Vehicle getObject(String type){

//check the type

if (type =="lamborghini"){

return new Vehicle.lamborghini();

} else if (type=="ApolloIE"){

return new Vehicle.ApolloIE();
}
return null;
}
}


Vehicle.java :


public class Vehicle {

void MakeNoise(){
System.out.println(" I ride like a Vehicle ");
}

void Horn(){
System.out.println(" I honk like a Vehicle ");
}

//New Lamborghini class
static class lamborghini extends Vehicle{

@Override
void MakeNoise(){
System.out.println("Vroom Vroom ! ");
}

@Override
void Horn() {
System.out.println(" I honk like a Lambo ");
}
}

//New Apollo Class
static class ApolloIE extends Vehicle{
@Override
void MakeNoise() {
System.out.println("ZOOOOOOMMMMMMM! Appollo");
}

@Override
void Horn() {
System.out.println("Apollo has No Horn !");
}
}


}



---------------------------------------------------------------



STRATEGY  PATTERN ( Behavioural Pattern ) :

It lets you define multiple algorithms or ways to solve a particular problem , and it automatically decides which strategy or algorithm to use on the RunTime.



useful blog : 
https://www.tutorialspoint.com/design_pattern/strategy_pattern.htm



public interface Strategy {

public default int dooperation(int num1, int num2){
return 0;
};
}



public class operationAdd implements Strategy{

@Override
public int dooperation(int num1, int num2) {
return num1+num2;
}
}


public class operationSub implements Strategy{
@Override
public int dooperation(int num1, int num2) {
return num1-num2;
}
}


public class operationMul implements Strategy {

@Override
public int dooperation(int num1, int num2) {
return num1*num2;
}
}



public class Context {

private static Strategy strategy;

public Context(Strategy strategy){
this.strategy=strategy;
}

public int execute(int num1,int num2){
return strategy.dooperation(num1,num2);
}

}


public class demo {
public static void main(String[] args0){


Context c= new Context(new operationAdd());
System.out.println(c.execute(1,2));


Context c2= new Context(new operationMul());
System.out.println(c.execute(1,2));


Context c3= new Context(new operationSub());
System.out.println(c.execute(1,2));


}
}






---------------------------------------------------------------

Useful blog : 
https://www.journaldev.com/1739/observer-design-pattern-in-java
https://www.youtube.com/watch?v=KkyFF8p5dVQ



Java provides inbuilt platform for implementing Observer pattern through java.util.Observable class and java.util.Observer interface



OBSERVER PATTERN ( Behavioural Pattern ) :


Observer pattern is used when there is one-to-many relationship between objects such as if one object is modified, its depenedent objects are to be notified automatically.
Eg - youtube notification.


The object which is being watched is called the subject. The objects which are watching the state changes are called observers or listeners.




public interface observer {
public void update(String productname);
}


public interface subject {

public void addObserver( observer observer);
public void removeObserver(observer observer);

public void notifyObservers();
}


public class customer implements observer{

private String customerName;

private subject subjectName;


public void setCustomerName(String name){
this.customerName=name;
}

@Override
public void update(String productname) {
System.out.println("Hello " + customerName+ ", " + productname + " is now available !");
}

}



import java.util.ArrayList;
import java.util.List;

public class product implements subject {

private boolean available;
private String productName;
private List<observer> observerList = new ArrayList<observer>();



public void setAvailable(boolean available){
this.available=available;

if (available == true){
notifyObservers();
}
}


public void setProductName(String productName){
this.productName=productName;
}

@Override
public void addObserver(observer observer) {
observerList.add(observer);
}

@Override
public void removeObserver(observer observer) {

observerList.remove(observer);
}

@Override
public void notifyObservers() {

for (observer observer : observerList) {

observer.update(productName);
}

}
}



public class demo {


public static void main(String[] args){

customer c1 = new customer();
c1.setCustomerName("Deepesh");


customer c2 = new customer();
c2.setCustomerName("Kiran");

product iphone12 = new product();
iphone12.setProductName("Iphone 12");


iphone12.setAvailable(false);

iphone12.addObserver(c1);
iphone12.addObserver(c2);

iphone12.setAvailable(true);
}
}




---------------------------------------------------------------



useful video : https://www.youtube.com/watch?v=k4EkJgY9P4c


BUILDER  PATTERN ( Creational Pattern ) :




In a traditional Object creation class , you need to define a series of variables and then set them inside the constructor. Due to this simple approach , when the number of parameters to a object is long , you need to pass in every variable as mentioned in object constructor.

By using Builder pattern you can CHOOSE , which attributes you want to set rathe rthan setting all at once during object creation. The rest of the variables are set to NULL (as in our case) , you can handle them accordingly.



public class demo {
public static void main(String[] args) {

// Phone phone = new Phone("Android","qualcommm","Samsung","8gb","128gb");

Phone phone = new PhoneBuilder().setOs("Android").setCompany("Samsung").getPhone();

System.out.println(phone);
}
}


public class Phone {

String os;
String processor;
String company;
String ram;
String storage;


public Phone(String os, String processor, String company, String ram, String storage) {
this.os = os;
this.processor = processor;
this.company = company;
this.ram = ram;
this.storage = storage;
}

@Override
public String toString() {
return "Phone : " + "os =" + os + " processor =" + processor + " company=" + company + " ram=" + ram + " storage=" + storage;
}
}



public class PhoneBuilder {

private String os;
private String processor;
private String company;
private String ram;
private String storage;

public PhoneBuilder setOs(String os) {
this.os = os;
return this;
}

public PhoneBuilder setProcessor(String processor) {
this.processor = processor;
return this;
}

public PhoneBuilder setCompany(String company) {
this.company = company;
return this;
}

public PhoneBuilder setRam(String ram) {
this.ram = ram;
return this;
}

public PhoneBuilder setStorage(String storage) {
this.storage = storage;
return this;
}


public Phone getPhone(){
return new Phone(os,processor,company,ram,storage);
}


}







---------------------------------------------------------------


Useful Video : https://www.geeksforgeeks.org/adapter-pattern/


ADAPTER PATTERN (Structural pattern) : 


It converts the Interface of a class to another interface.
It combines the functionalities of independent or incompatible  interfaces / classes.




public class demo {
public static void main(String[] args) {

Sparrow sparrow = new Sparrow();
ToyDuck toyDuck = new PlasticToyDuck();

// Wrap a bird in a birdAdapter so that it
// behaves like toy duck
ToyDuck birdAdapter = new BirdAdapter(sparrow);

System.out.println("Sparrow...");
sparrow.fly();
sparrow.makeSound();

System.out.println("ToyDuck...");
toyDuck.squeak();

// toy duck behaving like a bird
System.out.println("BirdAdapter...");
birdAdapter.squeak();
}
}


// Java implementation of Adapter pattern

interface Bird {
// birds implement Bird interface that allows
// them to fly and make sounds adaptee interface
public void fly();

public void makeSound();
}

class Sparrow implements Bird {
// a concrete implementation of bird
public void fly() {
System.out.println("Flying");
}

public void makeSound() {
System.out.println("Chirp Chirp");
}
}

interface ToyDuck {
// target interface
// toyducks dont fly they just make
// squeaking sound
public void squeak();
}

class PlasticToyDuck implements ToyDuck {
public void squeak() {
System.out.println("Squeak");
}
}

class BirdAdapter implements ToyDuck {
// You need to implement the interface your
// client expects to use.
Bird bird;

public BirdAdapter(Bird bird) {
// we need reference to the object we
// are adapting
this.bird = bird;
}

public void squeak() {
// translate the methods appropriately
bird.makeSound();
}
}





---------------------------------------------------------------


useful blog : https://www.geeksforgeeks.org/decorator-pattern-set-3-coding-the-design/?ref=lbp



DECORETOR PATTERN (structural pattern)



Decorator is a Conceptual pattern that allows adding new behaviors to objects dynamically by placing them inside special wrapper objects.


  • Decorators have the same super type as the object they decorate.
 

Pizza problem from the blog :


we have 2 pizza's SimplePizza and Margerita , We have 2 toppings , Paneer and FreshTomato.


public class demo {
public static void main(String[] args) {



//Margerita pizza with paneer and freshTomato toppings.
Pizza pizza1 = new Paneer(new FreshTomato(new Margherita()));

System.out.println(pizza1.getDescription());



}
}

// Java program to demonstrate Decorator
// pattern

// Abstract Pizza class (All classes extend
// from this)
abstract class Pizza {
// it is an abstract pizza
String description = "Unkknown Pizza";

public String getDescription() {
return description;
}

public abstract int getCost();
}






class SimplePizza extends Pizza {
public SimplePizza() {
description = "SimplePizza";
}

public int getCost() {
return 50;
}
}


class Margherita extends Pizza {
public Margherita() {
description = "Margherita";
}

public int getCost() {
return 100;
}
}


// The decorator class : It extends Pizza to be 
// interchangable with it topings decorator can
// also be implemented as an interface
abstract class ToppingsDecorator extends Pizza {
public abstract String getDescription();
}


class Paneer extends ToppingsDecorator {
Pizza pizza;

public Paneer(Pizza pizza) {
this.pizza = pizza;
}

public String getDescription() {
return pizza.getDescription() + ", Paneer ";
}

public int getCost() {
return 70 + pizza.getCost();
}
}


// Concrete toppings classes 
class FreshTomato extends ToppingsDecorator {
// we need a reference to obj we are decorating
Pizza pizza;

public FreshTomato(Pizza pizza) {
this.pizza = pizza;
}

public String getDescription() {
return pizza.getDescription() + ", Fresh Tomato ";
}

public int getCost() {
return 40 + pizza.getCost();
}
}



---------------------------------------------------------------


useful blog : https://dzone.com/articles/design-patterns-command


COMMAND PATTERN (Behavioural pattern) 


Its is used to avoid multiple If-else conditions and also if there is a need to undo .
It provides only

A command pattern have 3 things , Receiver , Invoker & a Client class.

Client - class which calls for the command from the invoker
Invoker - class which calls the execute method from the required Command class or the Receiver .
Receiver - class which runs the command.



For each command we create a Seperate class which implements the Command interface and override the 'execute' method. Then we create a Invoker class which has a Invoker method, which runs the 'execute' method from the given command class



public interface Command {
public void execute();
}



//Invoker
public class RemoteControl{
private Command command;
public void setCommand(Command command){
this.command = command;
}
public void pressButton(){
command.execute();
}
}



//Receiver
public class Light{
private boolean on;
public void switchOn(){
on = true;
}
public void switchOff(){
on = false;
}
}



//Concrete Command
public class LightOnCommand implements Command{
//reference to the light
Light light;
public LightOnCommand(Light light){
this.light = light;
}
public void execute(){
light.switchOn();
}
}




//Concrete Command
public class LightOffCommand implements Command{
//reference to the light
Light light;
public LightOffCommand(Light light){
this.light = light;
}
public void execute(){
light.switchOff();
}
}



//client
public class demo {
public static void main(String[] args) {

RemoteControl control = new RemoteControl();
Light light = new Light();
Command lightsOn = new LightOnCommand(light);
Command lightsOff = new LightOffCommand(light);
//switch on
control.setCommand(lightsOn);
control.pressButton();
//switch off
control.setCommand(lightsOff);
control.pressButton();
}
}





---------------------------------------------------------------



useful blog :  https://www.geeksforgeeks.org/facade-design-pattern-introduction/


FACADE PATTERN (Structural pattern) 

facade - means front of a building.

It acts as a Front interface for the client and Hides all the complexities in the Background , so that the client dont see the background complexities and only gets the interface to cares only about what the interfa e does then what is done in the background.

Eg - Java.sql.connection  class , we care only about the methods and what it does , than what is done in the background.


see blog .




---------------------------------------------------------------



useful blog :
 https://refactoring.guru/design-patterns/bridge
https://www.journaldev.com/1491/bridge-design-pattern-java
https://www.geeksforgeeks.org/bridge-design-pattern/


BRIDGE PATTERN : 

The Bridge design pattern allows you to separate the abstraction from the implementation




---------------------------------------------------------------


useful blog : https://www.journaldev.com/1572/proxy-design-pattern


PROXY PATTERN (Structural pattern) 


Controls and manage access to the object they are protecting.


4 types of proxy pattern: 

1] Remote 
2] Vitual 
3] Protection 
4] Smart 




---------------------------------------------------------------


https://en.wikipedia.org/wiki/Null_object_pattern


NULL OBJECT PATTERN (Behavioural pattern) 


It is a pattern in which whenever we want to handle a null object returned by another method , rather than using if else conditions , we create a Class (also called null class), this class will be extending to the class that is expected by the client and all the methods inside this null class we be empty i.e will do nothing.





// The code does 2 things , first ask for a object
// from a method and invokes a method on that object.
// we dont use "if/else" conditions to handle null
// pointer exception , rather we use a Null Object Pattern.


// We give a Animal class name to the getobject() method ,
// which return the Animal subclass if present in the "objectlist".
// if the provided input or class Name is
// not present in the objectlist , we return the Null Object ,
// which prevents the Null pointer error when
// a method is called on that object and in return does nothing.


public class demo {

String[] objectlist = {"Monkey", "Dog", "Tiger"};

public static void main(String[] args) {


Animal animal1 = getobject("IAmGivingWrongInput");

animal1.makesound();

}

public static Animal getobject(String animalname) {

//null object if animal name not found in the list.
return switch (animalname) {
case "Monkey" -> new Monkey();
case "Dog" -> new Dog();
case "Tiger" -> new Tiger();
default -> new NullAnimal();
};

}

}

class Animal {
void makesound() {
System.out.println("Default animal sound !");
}
}


class Monkey extends Animal {
@Override
void makesound() {
System.out.println("Monkey roars !");
}
}


class Dog extends Animal {
@Override
void makesound() {
System.out.println("Dog barks !");
}
}


class Tiger extends Animal {
@Override
void makesound() {
System.out.println("Tiger roars !");
}
}


class NullAnimal extends Animal {
@Override
void makesound() {
//Empty body
}
}










---------------------------------------------------------------

Good blog.
useful blog : https://www.journaldev.com/1763/template-method-design-pattern-in-java




TEMPLATE METHOD PATTERN (Behavioural pattern) 


Template Method consists of a set of methods called in a ordered manner.
The clients or users can change or override the Methods inside the Template method , but they cannot change or override the Template method itself and its order of methods.

 The Template Method is always "Final", so that the users cannot ovveride it and change the order of steps or methods called inside it.







---------------------------------------------------------------


useful blog : 
https://www.journaldev.com/1535/composite-design-pattern-in-java.
https://www.baeldung.com/java-composite-pattern


COMPOSITE PATTERN (Structural pattern) 

It helps to create a part-whole hierarchy. 

It helps to describe the relationship between different objects & define  a tree hierarchy to show what object is a part of what object. 
Eg - computer is a whole system & keyboard mouse are the computer parts .

The upper object of the tree holds the list of all the objects below or under it .

The Composite and all the objects under it must contain some common methods 



import java.util.ArrayList;
import java.util.List;

public class Computer {

//list of all the parts under computer
//as of now we use only keyboard & mouse , but we can add more
List<ComputerPart> parts = new ArrayList<>();

void addPart(ComputerPart computerPart){
parts.add(computerPart);
}

int getTotalPrice(){

//returns the total price of all the price added inside the parts list.
int Totalprice=0;
for (ComputerPart i : parts){
Totalprice= Totalprice + i.getPrice();
}
return Totalprice;
}

}


public class ComputerPart {

public ComputerPart(int price){
this.price=price;
}

int price;

int getPrice(){
return price;
}

}


public class Keyboard extends ComputerPart{

Keyboard(int price) {
super(price);
}

@Override
int getPrice() {
return this.price;
}
}


public class Mouse extends ComputerPart {

Mouse(int price) {
super(price);
}

@Override
int getPrice() {
return this.price;
}
}



public class demo {

public static void main(String[] args) {

Computer c = new Computer();

c.addPart(new Keyboard(100));
c.addPart(new Keyboard(100));
c.addPart(new Keyboard(100));
c.addPart(new Mouse(20));

System.out.println(c.getTotalPrice());
//returns 320.


}
}




---------------------------------------------------------------


useful blog :
 https://www.journaldev.com/1440/prototype-design-pattern-in-java


PROTOTYPE PATTERN (Creational pattern) 


Prototype design pattern is used when the Object creation is a costly affair and requires a lot of time and resources and you have a similar object already existing.


The idea of this pattern is very simple , that is to make a deep or shallow copy depending on the condition and then make changes accordingly to the object attributes and functions.




---------------------------------------------------------------


useful blog : 
https://www.journaldev.com/1751/state-design-pattern-java


STATE PATTERN : 

This pattern is used when we want to change the state of the object to do different things based on different object type.
The idea is to avoid using if/else conditions and to use CONTEXT Class to identify the given object type and call the necessary method.


eg - Tv remote ,Rather than using on/of conditions we can use State class and Context to call required method. See the blog for more.



public abstract class State {
void doaction() {
}
}

public class TvOnState extends State{
@Override
void doaction() {
System.out.println("Tv is On !");
}
}

public class TvOffState extends State{
@Override
void doaction() {
System.out.println("Tv is Off !");
}
}

public class RemoteContextClass extends State{

State tvState;

void setTvState(State tvState){
this.tvState=tvState;
}

@Override
void doaction() {
if (tvState != null){
tvState.doaction();
}
else {
System.out.println("tvState maybe Null");
}
}
}

public class demo {

public static void main(String[] args) {

RemoteContextClass remoteContextClass = new RemoteContextClass();

remoteContextClass.setTvState(new TvOnState());
remoteContextClass.doaction();

remoteContextClass.setTvState(new TvOffState());
remoteContextClass.doaction();

}
}






---------------------------------------------------------------


Useful blog : 
https://www.tutorialspoint.com/design_pattern/abstract_factory_pattern.htm



ABSTRACT FACTORY PATTERN : 

It is also called Factory of factory methods, because it contains a set of factory pattern methods.



The idea of this pattern is pretty simple have a bunch of factory methods inside a single Method. The client calls this Single method to call a specific factory and uses that factory to give out specific type of object.

Thats why this pattern is also called Factory of Factories.




see blog for more


---------------------------------------------------------------


useful blog : 
http://www.newthinktank.com/2012/10/chain-of-responsibility-design-pattern-tutorial/



CHAIN OF RESPONSIBILITY PATTERN : 


In this pattern , a single request is send form the client to a object, if the object cannot process that request it passes that request to the next object in the chain.


In this you define a "Chain" interface which contains 2 things , first the reference to the next object after this in chain , second the logic to be calculated.
All the objects implement this Interface and implement these 2 things. 




see the blog for the code




---------------------------------------------------------------



















































Comments

Popular posts from this blog

React Js + React-Redux (part-2)

React Js + CSS Styling + React Router (part-1)

ViteJS (Module Bundlers, Build Tools)