0% found this document useful (0 votes)
4 views

Design Patterns in java

Design patterns are established solutions for common programming problems that enhance code flexibility, reusability, and maintainability. They are categorized into creational, structural, and behavioral patterns, with specific examples such as Factory, Singleton, and Adapter patterns. Understanding and applying design patterns is crucial for professional software development, as they provide proven strategies for system architecture and design.

Uploaded by

yogitas804
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Design Patterns in java

Design patterns are established solutions for common programming problems that enhance code flexibility, reusability, and maintainability. They are categorized into creational, structural, and behavioral patterns, with specific examples such as Factory, Singleton, and Adapter patterns. Understanding and applying design patterns is crucial for professional software development, as they provide proven strategies for system architecture and design.

Uploaded by

yogitas804
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 71

Design Patterns

A design patterns are well-proved solution for solving


the specific problem/task.
Design patterns are programming language
independent strategies for solving the common object-
oriented design problems. That means, a design
pattern represents an idea, not a particular
implementation.
By using the design patterns you can make your code
more flexible, reusable and maintainable. It is the most
important part because java internally follows design
patterns.
To become a professional software developer, you must
know at least some popular solutions (i.e. design
patterns) to the coding problems.

Advantage of design pattern:


 They are reusable in multiple projects.
 They provide the solutions that help to define the
system architecture.
 They capture the software engineering
experiences.
 They provide transparency to the design of an
application.
 They are well-proved and testified solutions since
they have been built upon the knowledge and
experience of expert software developers.
 Design patterns don?t guarantee an absolute
solution to a problem. They provide clarity to the
system architecture and the possibility of building
a better system.
When should we use the design patterns?
 We must use the design patterns during the
analysis and requirement phase of SDLC(Software
Development Life Cycle).
 Design patterns ease the analysis and requirement
phase of SDLC by providing information based on
prior hands-on experiences.

Categorization of design patterns:


Basically, design patterns are categorized into two
parts:
 Core Java (or JSE) Design Patterns.
 JEE Design Patterns.

Core Java Design Patterns


In core java, there are mainly three types of design
patterns, which are further divided into their sub-parts:
 Creational Design Pattern
o Factory Pattern
o Abstract Factory Pattern
o Singleton Pattern
o Prototype Pattern
o Builder Pattern.

 Structural Design Pattern


o Adapter Pattern
o Bridge Pattern
o Composite Pattern
o Decorator Pattern
o Facade Pattern
o Flyweight Pattern
o Proxy Pattern

 Behavioural Design Pattern


o Chain Of Responsibility Pattern
o Command Pattern
o Interpreter Pattern
o Iterator Pattern
o Mediator Pattern
o Memento Pattern
o Observer Pattern
o State Pattern
o Strategy Pattern
o Template Pattern
o Visitor Pattern

History of Design Pattern


 Christopher Alexander was the first person who
invented all the above Design Patterns in 1977.
 But later the Gang of Four - Design patterns,
elements of reusable object-oriented software book
was written by a group of four persons named as
Erich Gamma, Richard Helm, Ralph Johnson and
John Vlissides in 1995.
 That's why all the above 23 Design Patterns are
known as Gang of Four (GoF) Design Patterns.
Creational design patterns
Creational design patterns are concerned with the way
of creating objects. These design patterns are used
when a decision must be made at the time of
instantiation of a class (i.e. creating an object of a
class).
Types of creational design patterns
There are following 5 types of creational design
patterns.
 Factory Method Pattern
 Abstract Factory Pattern
 Singleton Pattern
 Prototype Pattern
 Builder 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.

Advantage of Factory Design Pattern


 Factory Method Pattern allows the sub-classes to
choose the type of objects to create.
 It promotes the loose-coupling by eliminating the
need to bind application-specific classes into the
code. That means the code interacts solely with
the resultant interface or abstract class, so that it
will work with any classes that implement that
interface or that extends that abstract class.

Usage of Factory Design Pattern


 When a class doesn't know what sub-classes will
be required to create
 When a class wants that its sub-classes specify the
objects to be created.
 When the parent classes choose the creation of
objects to its sub-classes.

UML for Factory Method Pattern


 We are going to create a Plan abstract class and
concrete classes that extends the Plan abstract
class. A factory class GetPlanFactory is defined as
a next step.
 GenerateBill class will use GetPlanFactory to get a
Plan object. It will pass information
(DOMESTICPLAN / COMMERCIALPLAN /
INSTITUTIONALPLAN) to GetPalnFactory to get the
type of object it needs.

Calculate Electricity Bill : A Real World Example


of Factory Method
GenerateBill.java
Abstract Factory Pattern
Abstract Factory Pattern says that just define an
interface or abstract class for creating families of
related (or dependent) objects but without specifying
their concrete sub-classes.That means Abstract Factory
lets a class returns a factory of classes. So, this is the
reason that Abstract Factory Pattern is one level higher
than the Factory Pattern.
An Abstract Factory Pattern is also known as Kit.

Advantage of Abstract Factory Pattern


 Abstract Factory Pattern isolates the client code
from concrete (implementation) classes.
 It eases the exchanging of object families.
 It promotes consistency among objects.

Usage of Abstract Factory Pattern


 When the system needs to be independent of how
its object are created, composed, and represented.
 When the family of related objects has to be used
together, then this constraint needs to be
enforced.
 When you want to provide a library of objects that
does not show implementations and only reveals
interfaces.
 When the system needs to be configured with one
of a multiple family of objects.

UML for Abstract Factory Pattern


 We are going to create a Bank interface and a Loan
abstract class as well as their sub-classes.
 Then we will create AbstractFactory class as next
step.
 Then after we will create concrete classes,
BankFactory, and LoanFactory that will extends
AbstractFactory class
 After that, AbstractFactoryPatternExample class
uses the FactoryCreator to get an object of
AbstractFactory class.

Example of Abstract Factory Pattern


Here, we are calculating the loan payment for different
banks like HDFC, ICICI, SBI etc.
Singleton design pattern in Java
Singleton Pattern says that just “define a class that has
only one instance and provides a global point of access
to it”.
In other words, a class must ensure that only single
instance should be created and single object can be
used by all other classes.

There are two forms of singleton design pattern


 Early Instantiation: creation of instance at load
time.
 Lazy Instantiation: creation of instance when
required.

Advantage of Singleton design pattern


Saves memory because object is not created at each
request. Only single instance is reused again and again.

Usage of Singleton design pattern


Singleton pattern is mostly used in multi-threaded and
database applications. It is used in logging, caching,
thread pools, configuration settings etc.

Uml of Singleton design pattern


How to create Singleton design pattern?
To create the singleton class, we need to have static
member of class, private constructor and static factory
method.
 Static member: It gets memory only once because
of static, itcontains the instance of the Singleton
class.
 Private constructor: It will prevent to instantiate
the Singleton class from outside the class.
 Static factory method: This provides the global
point of access to the Singleton object and returns
the instance to the caller.
Prototype Design Pattern
Prototype Pattern says that cloning of an existing object
instead of creating new one and can also be
customized as per the requirement.
This pattern should be followed, if the cost of creating a
new object is expensive and resource intensive.

Advantage of Prototype Pattern


The main advantages of prototype pattern are as
follows:
 It reduces the need of sub-classing.
 It hides complexities of creating objects.
 The clients can get new objects without knowing
which type of object it will be.
 It lets you add or remove objects at runtime.

Usage of Prototype Pattern


 When the classes are instantiated at runtime.
 When the cost of creating an object is expensive or
complicated.
 When you want to keep the number of classes in
an application minimum.
 When the client application needs to be unaware of
object creation and representation.

UML for Prototype Pattern


 We are going to create an interface Prototype that
contains a method getClone() of Prototype type.
 Then, we create a concrete class EmployeeRecord
which implements Prototype interface that does
the cloning of EmployeeRecord object.
 PrototypeDemo class will uses this concrete class
EmployeeRecord.

Example of Prototype Design Pattern


Let's see the example of prototype design pattern.
File: Prototype.java
interface Prototype
{
public Prototype getClone();
}

File: EmployeeRecord.java
class EmployeeRecord implements Prototype
{
private int id;
private String name, designation;
private double salary;
private String address;

public EmployeeRecord()
{
System.out.println(" Employee Records
of Oracle Corporation ");
System.out.println("---------------------------------------------");
System.out.println("Eid"+"\
t"+"Ename"+"\t"+"Edesignation"+"\t"+"Esalary"+"\t\
t"+"Eaddress");
}

public EmployeeRecord(int id, String name, String


designation, double salary, String address)
{
this();
this.id = id;
this.name = name;
this.designation = designation;
this.salary = salary;
this.address = address;
}

public void showRecord()


{
System.out.println(id+"\t"+name+"\
t"+designation+"\t"+salary+"\t"+address);
}

@Override
public Prototype getClone()
{
return new
EmployeeRecord(id,name,designation,salary,address);
}
}

File: PrototypeDemo.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

class PrototypeDemo
{
public static void main(String[] args) throws
IOException
{
BufferedReader br =new
BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter Employee Id: ");
int eid=Integer.parseInt(br.readLine());
System.out.print("\n");

System.out.print("Enter Employee Name:


");
String ename=br.readLine();
System.out.print("\n");
System.out.print("Enter Employee
Designation: ");
String edesignation=br.readLine();
System.out.print("\n");

System.out.print("Enter Employee
Address: ");
String eaddress=br.readLine();
System.out.print("\n");

System.out.print("Enter Employee Salary:


");
double esalary=
Double.parseDouble(br.readLine());
System.out.print("\n");

EmployeeRecord e1=new
EmployeeRecord(eid,ename,edesignation,esalary,eaddr
ess);

e1.showRecord();
System.out.println("\n");
EmployeeRecord e2=(EmployeeRecord)
e1.getClone();
e2.showRecord();
}
}
Builder Design Pattern
Builder Pattern says that "construct a complex object
from simple objects using step-by-step approach"
It is mostly used when object can't be created in single
step like in the de-serialization of a complex object.

Advantage of Builder Design Pattern


The main advantages of Builder Pattern are as follows:
 It provides clear separation between the
construction and representation of an object.
 It provides better control over construction
process.
 It supports to change the internal representation of
objects.
Structural design patterns
Structural design 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.

Types of structural design patterns


There are following 7 types of structural design
patterns.
 Adapter Pattern - Adapting an interface into
another according to client expectation.
 Bridge Pattern - Separating abstraction
(interface) from implementation.
 Composite Pattern - Allowing clients to operate
on hierarchy of objects.
 Decorator Pattern - Adding functionality to an
object dynamically.
 Facade Pattern - Providing an interface to a set
of interfaces.
 Flyweight Pattern - Reusing an object by sharing
it.
 Proxy Pattern - Representing another object.
Adapter Pattern
An Adapter Pattern says that just "converts the
interface of a class into another interface that a client
wants".
In other words, to provide the interface according to
client requirement while using the services of a class
with a different interface.
The Adapter Pattern is also known as Wrapper.

Advantage of Adapter Pattern


 It allows two or more previously incompatible
objects to interact.
 It allows reusability of existing functionality.

Usage of Adapter pattern:


It is used:
 When an object needs to utilize an existing class
with an incompatible interface.
 When you want to create a reusable class that
cooperates with classes which don't have
compatible interfaces.
 When you want to create a reusable class that
cooperates with classes which don't have
compatible interfaces.

Example of Adapter Pattern


Bridge Pattern
A Bridge Pattern says that just "decouple the functional
abstraction from the implementation so that the two
can vary independently".
The Bridge Pattern is also known as Handle or Body.

Advantage of Bridge Pattern


 It enables the separation of implementation from
the interface.
 It improves the extensibility.
 It allows the hiding of implementation details from
the client.

Usage of Bridge Pattern


 When you don't want a permanent binding
between the functional abstraction and its
implementation.
 When both the functional abstraction and its
implementation need to extended using sub-
classes.
 It is mostly used in those places where changes are
made in the implementation does not affect the
clients.

Example of Bridge Pattern


Question.java
public interface Question
{
public void nextQuestion();
public void previousQuestion();
public void newQuestion(String q);
public void deleteQuestion(String q);
public void displayQuestion();
public void displayAllQuestions();
}

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

public class JavaQuestions implements Question


{
private List<String> questions = new
ArrayList<String>();
private int current = 0;

public JavaQuestions()
{
questions.add("What is class? ");
questions.add("What is interface? ");
questions.add("What is abstraction? ");
questions.add("How multiple polymorphism is
achieved in java? ");
questions.add("How many types of exception
handling are there in java? ");
questions.add("Define the keyword final for
variable, method, and class in java? ");
questions.add("What is abstract class? ");
questions.add("What is multi-threading? ");
}

public void nextQuestion()


{
if (current <= questions.size() - 1)
current++;
System.out.print(current);
}

public void previousQuestion()


{
if (current > 0)
current--;
}

public void newQuestion(String quest)


{
questions.add(quest);
}
public void deleteQuestion(String quest)
{
questions.remove(quest);
}

public void displayQuestion()


{
System.out.println(questions.get(current));
}

public void displayAllQuestions()


{
for (String quest : questions)
{
System.out.println(quest);
}
}
}

QuestionManager.java
public class QuestionManager
{
protected Question q;
public String catalog;
public QuestionManager(String catalog)
{
this.catalog = catalog;
}

public void next()


{
q.nextQuestion();
}

public void previous()


{
q.previousQuestion();
}

public void newOne(String quest)


{
q.newQuestion(quest);
}

public void delete(String quest)


{
q.deleteQuestion(quest);
}
public void display()
{
q.displayQuestion();
}

public void displayAll()


{
System.out.println("Question Paper: " +
catalog);
q.displayAllQuestions();
}
}

QuestionFormat.java
public class QuestionFormat extends QuestionManager
{
public QuestionFormat(String catalog)
{
super(catalog);
}

public void displayAll()


{
System.out.println("\
n---------------------------------------------------------");
super.displayAll();

System.out.println("--------------------------------------------------
---------");
}
}

BridgePatternDemo.java
public class BridgePatternDemo
{
public static void main(String[] args)
{
QuestionFormat questions = new
QuestionFormat("Java Programming Language");
questions.q = new JavaQuestions();
questions.delete("what is class?");
questions.display();
questions.newOne("What is inheritance? ");

questions.newOne("How many types of


inheritance are there in java?");
questions.displayAll();
}
}
Composite Pattern
A Composite Pattern says that just "allow clients to
operate in generic manner on objects that may or may
not represent a hierarchy of objects".

Advantage of Composite Design Pattern


 It defines class hierarchies that contain primitive
and complex objects.
 It makes easier to you to add new kinds of
components.
 It provides flexibility of structure with manageable
class or interface.

Usage of Composite Pattern


It is used:
 When you want to represent a full or partial
hierarchy of objects.
 When the responsibilities are needed to be added
dynamically to the individual objects without
affecting other objects. Where the responsibility of
object may vary from time to time.

Elements used in Composite Pattern:


Let's see the 4 elements of composte pattern.
1) Component
 Declares interface for objects in composition.
 Implements default behavior for the interface
common to all classes as appropriate.
 Declares an interface for accessing and managing
its child components.
2) Leaf
 Represents leaf objects in composition. A leaf has
no children.
 Defines behavior for primitive objects in the
composition.
3) Composite
 Defines behavior for components having children.
 Stores child component.
 Implements child related operations in the
component interface.
4) Client
 Manipulates objects in the composition through the
component interface.

Example of Composite Pattern


Employee.java
public interface Employee
{
public int getId();

public String getName();

public double getSalary();

public void print();


public void add(Employee employee);

public void remove(Employee employee);

public Employee getChild(int i);


}

BankManager.java
// this is the BankManager class i.e. Composite.

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

public class BankManager implements Employee


{
private int id;
private String name;
private double salary;

public BankManager(int id, String name, double


salary)
{
this.id = id;
this.name = name;
this.salary = salary;
}

List<Employee> employees = new


ArrayList<Employee>();

@Override
public void add(Employee employee)
{
employees.add(employee);
}

@Override
public Employee getChild(int i)
{
return employees.get(i);
}

@Override
public void remove(Employee employee)
{
employees.remove(employee);
}
@Override
public int getId()
{
return id;
}

@Override
public String getName()
{
return name;
}

@Override
public double getSalary()
{
return salary;
}

@Override
public void print()
{

System.out.println("=====================
=====");
System.out.println("Id =" + getId());
System.out.println("Name =" + getName());
System.out.println("Salary =" + getSalary());

System.out.println("=====================
=====");

Iterator<Employee> it = employees.iterator();

while (it.hasNext())
{
Employee employee = it.next();
employee.print();
}
}
}

Cashier.java
public class Cashier implements Employee
{
/*
* In this class,there are many methods which are
not applicable to cashier
* because it is a leaf node.
*/
private int id;
private String name;
private double salary;

public Cashier(int id, String name, double salary)


{
this.id = id;
this.name = name;
this.salary = salary;
}

@Override
public void add(Employee employee)
{
// this is leaf node so this method is not
applicable to this class.
}

@Override
public Employee getChild(int i)
{
// this is leaf node so this method is not
applicable to this class.
return null;
}
@Override
public int getId()
{
// TODO Auto-generated method stub
return id;
}

@Override
public String getName()
{
return name;
}

@Override
public double getSalary()
{
return salary;
}

@Override
public void print()
{

System.out.println("=====================
=====");
System.out.println("Id =" + getId());
System.out.println("Name =" + getName());
System.out.println("Salary =" + getSalary());

System.out.println("=====================
=====");
}

@Override
public void remove(Employee employee)
{
// this is leaf node so this method is not
applicable to this class.
}
}

Accountant.java
public class Accountant implements Employee
{
/*
* In this class,there are many methods which are
not applicable to cashier
* because it is a leaf node.
*/
private int id;
private String name;
private double salary;

public Accountant(int id, String name, double


salary)
{
this.id = id;
this.name = name;
this.salary = salary;
}

@Override
public void add(Employee employee)
{
// this is leaf node so this method is not
applicable to this class.
}

@Override
public Employee getChild(int i)
{
// this is leaf node so this method is not
applicable to this class.
return null;
}
@Override
public int getId()
{
// TODO Auto-generated method stub
return id;
}

@Override
public String getName()
{
return name;
}

@Override
public double getSalary()
{
return salary;
}

@Override
public void print()
{

System.out.println("=====================
====");
System.out.println("Id =" + getId());
System.out.println("Name =" + getName());
System.out.println("Salary =" + getSalary());

System.out.println("=====================
====");
}

@Override
public void remove(Employee employee)
{
// this is leaf node so this method is not
applicable to this class.
}
}

CompositePatternDemo.java
public class CompositePatternDemo
{
public static void main(String args[])
{
Employee emp1 = new Cashier(101, "Sohan
Kumar", 20000.0);
Employee emp2 = new Cashier(102, "Mohan
Kumar", 25000.0);
Employee emp3 = new Accountant(103,
"Seema Mahiwal", 30000.0);
Employee manager1 = new
BankManager(100, "Ashwani Rajput", 100000.0);

manager1.add(emp1);
manager1.add(emp2);
manager1.add(emp3);
manager1.print();
}
}
Decorator Pattern
A Decorator Pattern says that just "attach a flexible
additional responsibilities to an object dynamically".
In other words, The Decorator Pattern uses composition
instead of inheritance to extend the functionality of an
object at runtime.
The Decorator Pattern is also known as Wrapper.

Advantage of Decorator Pattern


 It provides greater flexibility than static
inheritance.
 It enhances the extensibility of the object, because
changes are made by coding new classes.
 It simplifies the coding by allowing you to develop
a series of functionality from targeted classes
instead of coding all of the behavior into the
object.

Usage of Decorator Pattern


It is used:
 When you want to transparently and dynamically
add responsibilities to objects without affecting
other objects.
 When you want to add responsibilities to an object
that you may want to change in future.
 Extending functionality by sub-classing is no longer
practical.

Example of Decorator Pattern


Food.java
public interface Food
{
public String prepareFood();

public double foodPrice();


}

VegFood.java
public class VegFood implements Food
{
public String prepareFood()
{
return "Veg Food";
}

public double foodPrice()


{
return 50.0;
}
}

FoodDecorator.java
public abstract class FoodDecorator implements Food
{
private Food newFood;
public FoodDecorator(Food newFood)
{
this.newFood=newFood;
}
@Override
public String prepareFood()
{
return newFood.prepareFood();
}
public double foodPrice()
{
return newFood.foodPrice();
}
}

NonVegFood.java
public class NonVegFood extends FoodDecorator
{
public NonVegFood(Food newFood)
{
super(newFood);
}

public String prepareFood()


{
return super.prepareFood() + " With Roasted
Chiken and Chiken Curry ";
}

public double foodPrice()


{
return super.foodPrice() + 150.0;
}
}

ChineeseFood.java
public class ChineeseFood extends FoodDecorator
{
public ChineeseFood(Food newFood)
{
super(newFood);
}

public String prepareFood()


{
return super.prepareFood() + " With Fried Rice
and Manchurian ";
}
public double foodPrice()
{
return super.foodPrice() + 65.0;
}
}

DecoratorPatternCustomer.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class DecoratorPatternCustomer


{
private static int choice;

public static void main(String args[]) throws


NumberFormatException, IOException
{
do
{
System.out.print("========= Food
Menu ============ \n");
System.out.print(" 1. Vegetarian
Food. \n");
System.out.print(" 2. Non-
Vegetarian Food.\n");
System.out.print(" 3. Chineese
Food. \n");
System.out.print(" 4. Exit
\n");
System.out.print("Enter your choice: ");

BufferedReader br = new
BufferedReader(new InputStreamReader(System.in));
choice = Integer.parseInt(br.readLine());
switch (choice)
{
case 1:
{
VegFood vf = new VegFood();

System.out.println(vf.prepareFood());

System.out.println(vf.foodPrice());
}
break;

case 2:
{
Food f1 = new
NonVegFood((Food) new VegFood());
System.out.println(f1.prepareFood());

System.out.println(f1.foodPrice());
}
break;
case 3:
{
Food f2 = new
ChineeseFood((Food) new VegFood());

System.out.println(f2.prepareFood());

System.out.println(f2.foodPrice());
}
break;

default:
{
System.out.println("Other than
these no food available");
}
return;
}

} while (choice != 4);


}
}
Facade Pattern
A Facade Pattern says that just "just provide a unified
and simplified interface to a set of interfaces in a
subsystem, therefore it hides the complexities of the
subsystem from the client".
In other words, Facade Pattern describes a higher-level
interface that makes the sub-system easier to use.
Practically, every Abstract Factory is a type of Facade.

Advantage of Facade Pattern


 It shields the clients from the complexities of the
sub-system components.
 It promotes loose coupling between subsystems
and its clients.

Usage of Facade Pattern:


It is used:
 When you want to provide simple interface to a
complex sub-system.
 When several dependencies exist between clients
and the implementation classes of an abstraction.

Example of Facade Pattern


MobileShop.java
public interface MobileShop
{
public void modelNo();
public void price();
}

Iphone.java
public class Iphone implements MobileShop
{
@Override
public void modelNo()
{
System.out.println(" Iphone 6 ");
}

@Override
public void price()
{
System.out.println(" Rs 65000.00 ");
}
}

Samsung.java
public class Samsung implements MobileShop
{
@Override
public void modelNo()
{
System.out.println(" Samsung galaxy tab 3 ");
}

@Override
public void price()
{
System.out.println(" Rs 45000.00 ");
}
}

Blackberry.java
public class Blackberry implements MobileShop
{
@Override
public void modelNo()
{
System.out.println(" Blackberry Z10 ");
}

@Override
public void price()
{
System.out.println(" Rs 55000.00 ");
}
}
ShopKeeper.java
public class ShopKeeper
{
private MobileShop iphone;
private MobileShop samsung;
private MobileShop blackberry;

public ShopKeeper()
{
iphone = new Iphone();
samsung = new Samsung();
blackberry = new Blackberry();
}

public void iphoneSale()


{
iphone.modelNo();
iphone.price();
}

public void samsungSale()


{
samsung.modelNo();
samsung.price();
}

public void blackberrySale()


{
blackberry.modelNo();
blackberry.price();
}
}

FacadePatternClient.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class FacadePatternClient


{
private static int choice;

public static void main(String args[]) throws


NumberFormatException, IOException
{
do
{
System.out.print("========= Mobile
Shop ============ \n");
System.out.print(" 1. IPHONE.
\n");
System.out.print(" 2. SAMSUNG.
\n");
System.out.print(" 3. BLACKBERRY.
\n");
System.out.print(" 4. Exit.
\n");
System.out.print("Enter your choice: ");

BufferedReader br = new
BufferedReader(new InputStreamReader(System.in));
choice = Integer.parseInt(br.readLine());
ShopKeeper sk = new ShopKeeper();

switch (choice)
{
case 1:
{
sk.iphoneSale();
}
break;

case 2:
{
sk.samsungSale();
}
break;

case 3:
{
sk.blackberrySale();
}
break;

default:
{
System.out.println("Nothing You
purchased");
}
return;
}

} while (choice != 4);


}
}
Flyweight Pattern
A Flyweight Pattern says that just "to reuse already
existing similar kind of objects by storing them and
create new object when no matching object is found".

Advantage of Flyweight Pattern


 It reduces the number of objects.
 It reduces the amount of memory and storage
devices required if the objects are persisted

Usage of Flyweight Pattern


 When an application uses number of objects
 When the storage cost is high because of the
quantity of objects.
 When the application does not depend on object
identity.

Example of Flyweight Pattern


Proxy Pattern
Simply, proxy means an object representing another
object.
According to GoF, a Proxy Pattern "provides the control
for accessing the original object".
So, we can perform many operations like hiding the
information of original object, on demand loading etc.
Proxy pattern is also known as Surrogate or
Placeholder.
RMI API uses proxy design pattern. Stub and Skeleton
are two proxy objects used in RMI.

Advantage of Proxy Pattern


 It provides the protection to the original object
from the outside world.

Usage of Proxy Pattern:


It is used:
 It can be used in Virtual Proxy scenario---Consider
a situation where there is multiple database call to
extract huge size image. Since this is an expensive
operation so here we can use the proxy pattern
which would create multiple proxies and point to
the huge size memory consuming object for further
processing. The real object gets created only when
a client first requests/accesses the object and after
that we can just refer to the proxy to reuse the
object. This avoids duplication of the object and
hence saving memory.
 It can be used in Protective Proxy scenario---It acts
as an authorization layer to verify that whether the
actual user has access the appropriate content or
not. For example, a proxy server which provides
restriction on internet access in office. Only the
websites and contents which are valid will be
allowed and the remaining ones will be blocked.
 It can be used in Remote Proxy scenario---A remote
proxy can be thought about the stub in the RPC
call. The remote proxy provides a local
representation of the object which is present in the
different address location. Another example can be
providing interface for remote resources such as
web service or REST resources.
 It can be used in Smart Proxy scenario---A smart
proxy provides additional layer of security by
interposing specific actions when the object is
accessed. For example, to check whether the real
object is locked or not before accessing it so that
no other objects can change it.

Example of Proxy Pattern


OfficeInternetAccess.java
public interface OfficeInternetAccess
{
public void grantInternetAccess();
}

RealInternetAccess.java
public class RealInternetAccess implements
OfficeInternetAccess
{
private String employeeName;

public RealInternetAccess(String empName)


{
this.employeeName = empName;
}

@Override
public void grantInternetAccess()
{
System.out.println("Internet Access granted
for employee: " + employeeName);
}
}

ProxyInternetAccess.java
public class ProxyInternetAccess implements
OfficeInternetAccess
{
private String employeeName;
private RealInternetAccess realaccess;

public ProxyInternetAccess(String employeeName)


{
this.employeeName = employeeName;
}

@Override
public void grantInternetAccess()
{
if (getRole(employeeName) > 4)
{
realaccess = new
RealInternetAccess(employeeName);
realaccess.grantInternetAccess();
}
else
{
System.out.println("No Internet access
granted. Your job level is below 5");
}
}

public int getRole(String emplName)


{
// Check role from the database based on
Name and designation
// return job level or job designation.
return 9;
}
}

ProxyPatternClient.java
public class ProxyPatternClient
{
public static void main(String[] args)
{
OfficeInternetAccess access = new
ProxyInternetAccess("Ashwani Rajput");
access.grantInternetAccess();
}
}
Behavioral Design Patterns
Behavioral design 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.
That means the implementation and the client should
be loosely coupled in order to avoid hard coding and
dependencies.
There are 12 types of behavioral design patterns:
 Chain of Responsibility Pattern
 Command Pattern
 Interpreter Pattern
 Iterator Pattern
 Mediator Pattern
 Memento Pattern
 Observer Pattern
 State Pattern
 Strategy Pattern
 Template Pattern
 Visitor Pattern
 Null Object
Chain Of Responsibility Pattern
In chain of responsibility, sender sends a request to a
chain of objects. The request can be handled by any
object in the chain.
A Chain of Responsibility Pattern says that just "avoid
coupling the sender of a request to its receiver by
giving multiple objects a chance to handle the request".
For example, an ATM uses the Chain of Responsibility
design pattern in money giving process.
In other words, we can say that normally each receiver
contains reference of another receiver. If one object
cannot handle the request then it passes the same to
the next receiver and so on.

Advantage of Chain of Responsibility Pattern


 It reduces the coupling.
 It adds flexibility while assigning the
responsibilities to objects.
 It allows a set of classes to act as one; events
produced in one class can be sent to other handler
classes with the help of composition.

Usage of Chain of Responsibility Pattern:


It is used:
 When more than one object can handle a request
and the handler is unknown.
 When the group of objects that can handle the
request must be specified in dynamic way.

Example of Chain of Responsibility Pattern


Logger.java
public abstract class Logger
{
public static int OUTPUTINFO = 1;
public static int ERRORINFO = 2;
public static int DEBUGINFO = 3;
protected int levels;
protected Logger nextLevelLogger;

public void setNextLevelLogger(Logger


nextLevelLogger)
{
this.nextLevelLogger = nextLevelLogger;
}

public void logMessage(int levels, String msg)


{
if (this.levels <= levels)
{
displayLogInfo(msg);
}
if (nextLevelLogger != null)
{
nextLevelLogger.logMessage(levels, msg);
}
}

protected abstract void displayLogInfo(String msg);


}

ConsoleBasedLogger.java
public class ConsoleBasedLogger extends Logger
{
public ConsoleBasedLogger(int levels)
{
this.levels = levels;
}

@Override
protected void displayLogInfo(String msg)
{
System.out.println("CONSOLE LOGGER INFO: "
+ msg);
}
}

DebugBasedLogger.java
public class DebugBasedLogger extends Logger
{
public DebugBasedLogger(int levels)
{
this.levels = levels;
}

@Override
protected void displayLogInfo(String msg)
{
System.out.println("DEBUG LOGGER INFO: " +
msg);
}
}

ErrorBasedLogger.java
public class ErrorBasedLogger extends Logger
{
public ErrorBasedLogger(int levels)
{
this.levels = levels;
}

@Override
protected void displayLogInfo(String msg)
{
System.out.println("ERROR LOGGER INFO: " +
msg);
}
}

ChainofResponsibilityClient.java
public class ChainofResponsibilityClient
{
private static Logger doChaining()
{
Logger consoleLogger = new
ConsoleBasedLogger(Logger.OUTPUTINFO);

Logger errorLogger = new


ErrorBasedLogger(Logger.ERRORINFO);

consoleLogger.setNextLevelLogger(errorLogger);

Logger debugLogger = new


DebugBasedLogger(Logger.DEBUGINFO);

errorLogger.setNextLevelLogger(debugLogger);

return consoleLogger;
}

public static void main(String args[])


{
Logger chainLogger = doChaining();

chainLogger.logMessage(Logger.OUTPUTINFO,
"Enter the sequence of values ");
chainLogger.logMessage(Logger.ERRORINFO,
"An error is occured now");
chainLogger.logMessage(Logger.DEBUGINFO,
"This was the error now debugging is compeled");
}
}

You might also like