0% found this document useful (0 votes)
9 views26 pages

Java Design Patterns

The document provides an overview of various Java design patterns categorized into creational, structural, and behavioral types. It details specific patterns such as Singleton, Factory, Observer, and Strategy, explaining their purposes and implementations. Additionally, it includes code snippets illustrating the Observer design pattern with interfaces and classes for observers and subjects.

Uploaded by

Lo Se R
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as ODT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views26 pages

Java Design Patterns

The document provides an overview of various Java design patterns categorized into creational, structural, and behavioral types. It details specific patterns such as Singleton, Factory, Observer, and Strategy, explaining their purposes and implementations. Additionally, it includes code snippets illustrating the Observer design pattern with interfaces and classes for observers and subjects.

Uploaded by

Lo Se R
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as ODT, PDF, TXT or read online on Scribd
You are on page 1/ 26

Design Pattern (Solution to common problems)

0. What are design patterns and types.


1. Observer Design Pattern
2. SINGLETON
2.1. INITIALIZATION ON DEMAND HOLDER
3. THE STRATEGY AND THE FACTORY PATTERN
4. FLUENT BUILDER
5. CHAIN OF RESPONSIBILITY
6. TEMPLATE METHOD
7. STATE PATTERN
8. Callback Pattern
9. Prototype Design Pattern
10. Memento design pattern

0. What are design patterns and types.


Java Design Patterns are divided into three categories – creational, structural, and
behavioral design patterns.
This post serves as an index for all the java design patterns articles I have written so far.

#Creational Design Patterns


Singleton Pattern
Factory Pattern
Abstract Factory Pattern
Builder Pattern
Prototype Pattern
#Structural Design Patterns
Adapter Pattern
Composite Pattern
Proxy Pattern
Flyweight Pattern
Facade Pattern
Bridge Pattern
Decorator Pattern
#Behavioral Design Patterns
Template Method Pattern
Mediator Pattern
Chain of Responsibility Pattern
Observer Pattern
Strategy Pattern
Command Pattern
State Pattern
Visitor Pattern
Interpreter Pattern
Iterator Pattern
Memento Pattern

#Creational Design Patterns


Creational design patterns provide solution to instantiate an object in the best possible
way for specific situations.
#Singleton Pattern
Singleton pattern restricts the instantiation of a class and ensures that only one instance
of the class exists in the java virtual machine. It seems to be a very simple design pattern
but when it comes to implementation, it comes with a lot of implementation concerns.
The implementation of Singleton pattern has always been a controversial topic among
developers. Check out Singleton Design Pattern to learn about different ways to
implement Singleton pattern and pros and cons of each of the method.
This is one of the most discussed java design patterns.

#Factory Pattern
Factory design pattern is used when we have a super class with multiple sub-classes and
based on input,
we need to return one of the sub-class. This pattern take out the responsibility of
instantiation of a
class from client program to the factory class. We can apply Singleton pattern on Factory
class or make the factory
method static. This is one of the most widely used java design pattern.

#Abstract Factory Pattern


Abstract Factory pattern is similar to Factory pattern and it’s factory of factories. If you
are familiar with factory design pattern in java, you will notice that we have a single
Factory class that returns the different sub-classes based on the input provided and
factory class uses if-else or switch statement to achieve this.

In Abstract Factory pattern, we get rid of if-else block and have a factory class for each
sub-class and then an Abstract Factory class that will return the sub-class based on the
input factory class. Check out Abstract Factory Pattern to know how to implement this
pattern with example program.

#Builder Pattern
This pattern was introduced to solve some of the problems with Factory and Abstract
Factory design patterns when the Object contains a lot of attributes. Builder pattern
solves the issue with large number of optional parameters and inconsistent state by
providing a way to build the object step-by-step and provide a method that will actually
return the final Object. Check out Builder Pattern for example program and classes used
in JDK.

#Prototype Pattern
Prototype 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. So this pattern
provides a mechanism to copy the original object to a new object and then modify it
according to our needs. This pattern uses java cloning to copy the object.

Prototype design pattern mandates that the Object which you are copying should provide
the copying feature. It should not be done by any other class. However whether to use
shallow or deep copy of the Object properties depends on the requirements and its a
design decision. Check out Prototype Pattern for sample program.
#Structural Design Patterns
Structural patterns provide different ways to create a class structure, for example using
inheritance and composition to create a large object from small objects.

#Adapter Pattern
Adapter design pattern is one of the structural design pattern and its used so that two
unrelated interfaces can work together. The object that joins these unrelated interface is
called an Adapter. As a real life example, we can think of a mobile charger as an adapter
because mobile battery needs 3 volts to charge but the normal socket produces either
120V (US) or 240V (India). So the mobile charger works as an adapter between mobile
charging socket and the wall socket. Check out Adapter Pattern for example program and
it’s usage in Java.

#Composite Pattern
Composite pattern is one of the Structural design pattern and is used when we have to
represent a part-whole hierarchy. When we need to create a structure in a way that the
objects in the structure has to be treated the same way, we can apply composite design
pattern.

Lets understand it with a real life example – A diagram is a structure that consists of
Objects such as Circle, Lines, Triangle etc and when we fill the drawing with color (say
Red), the same color also gets applied to the Objects in the drawing. Here drawing is
made up of different parts and they all have same operations. Check out Composite
Pattern article for different component of composite pattern and example program.

#Proxy Pattern
Proxy pattern intent is to “Provide a surrogate or placeholder for another object to control
access to it”. The definition itself is very clear and proxy pattern is used when we want to
provide controlled access of a functionality.

Let’s say we have a class that can run some command on the system. Now if we are
using it, its fine but if we want to give this program to a client application, it can have
severe issues because client program can issue command to delete some system files or
change some settings that you don’t want. Check out Proxy Pattern post for the example
program with implementation details.

#Flyweight Pattern
Flyweight design pattern is used when we need to create a lot of Objects of a class. Since
every object consumes memory space that can be crucial for low memory devices, such
as mobile devices or embedded systems, flyweight design pattern can be applied to
reduce the load on memory by sharing objects. String Pool implementation in java is one
of the best example of Flyweight pattern implementation. Check out Flyweight Pattern
article for sample program and implementation process.

#Facade Pattern
Facade Pattern is used to help client applications to easily interact with the system.
Suppose we have an application with set of interfaces to use MySql/Oracle database and
to generate different types of reports, such as HTML report, PDF report etc. So we will
have different set of interfaces to work with different types of database. Now a client
application can use these interfaces to get the required database connection and
generate reports. But when the complexity increases or the interface behavior names are
confusing, client application will find it difficult to manage it. So we can apply Facade
pattern here and provide a wrapper interface on top of the existing interface to help
client application. Check out Facade Pattern post for implementation details and sample
program.

#Bridge Pattern
When we have interface hierarchies in both interfaces as well as implementations, then
bridge design pattern is used to decouple the interfaces from implementation and hiding
the implementation details from the client programs. Like Adapter pattern, its one of the
Structural design pattern.

The implementation of bridge design pattern follows the notion to prefer Composition
over inheritance. Check out Bridge Pattern post for implementation details and sample
program.

#Decorator Pattern
Decorator design pattern is used to modify the functionality of an object at runtime. At
the same time other instances of the same class will not be affected by this, so individual
object gets the modified behavior. Decorator design pattern is one of the structural
design pattern (such as Adapter Pattern, Bridge Pattern, Composite Pattern) and uses
abstract classes or interface with composition to implement.

We use inheritance or composition to extend the behavior of an object but this is done at
compile time and its applicable to all the instances of the class. We can’t add any new
functionality of remove any existing behavior at runtime – this is when Decorator pattern
comes into picture. Check out Decorator Pattern post for sample program and
implementation details.

#Behavioral Design Patterns


Behavioral patterns provide solution for the better interaction between objects and how
to provide lose coupling and flexibility to extend easily.

#Template Method Pattern


Template Method is a behavioral design pattern and it’s used to create a method stub and
deferring some of the steps of implementation to the subclasses. Template method
defines the steps to execute an algorithm and it can provide default implementation that
might be common for all or some of the subclasses.

Suppose we want to provide an algorithm to build a house. The steps need to be


performed to build a house are – building foundation, building pillars, building walls and
windows. The important point is that the we can’t change the order of execution because
we can’t build windows before building the foundation. So in this case we can create a
template method that will use different methods to build the house. Check out Template
Method Pattern post for implementation details with example program.
#Mediator Pattern
Mediator design pattern is used to provide a centralized communication medium between
different objects in a system. Mediator design pattern is very helpful in an enterprise
application where multiple objects are interacting with each other. If the objects interact
with each other directly, the system components are tightly-coupled with each other that
makes maintainability cost higher and not flexible to extend easily. Mediator pattern
focuses on provide a mediator between objects for communication and help in
implementing lose-coupling between objects.

Air traffic controller is a great example of mediator pattern where the airport control room
works as a mediator for communication between different flights. Mediator works as a
router between objects and it can have it’s own logic to provide way of communication.
Check out Mediator Pattern post for implementation details with example program.

#Chain of Responsibility Pattern


Chain of responsibility pattern is used to achieve lose coupling in software design where a
request from client is passed to a chain of objects to process them. Then the object in the
chain will decide themselves who will be processing the request and whether the request
is required to be sent to the next object in the chain or not.

We know that we can have multiple catch blocks in a try-catch block code. Here every
catch block is kind of a processor to process that particular exception. So when any
exception occurs in the try block, its send to the first catch block to process. If the catch
block is not able to process it, it forwards the request to next object in chain i.e next
catch block. If even the last catch block is not able to process it, the exception is thrown
outside of the chain to the calling program.

ATM dispense machine logic can be implemented using Chain of Responsibility Pattern,
check out the linked post.

#Observer Pattern
Observer design pattern is useful when you are interested in the state of an object and
want to get notified whenever there is any change. In observer pattern, the object that
watch on the state of another object are called Observer and the object that is being
watched is called Subject.

Java provides inbuilt platform for implementing Observer pattern through


java.util.Observable class and java.util.Observer interface. However it’s not widely used
because the implementation is really simple and most of the times we don’t want to end
up extending a class just for implementing Observer pattern as java doesn’t provide
multiple inheritance in classes.

Java Message Service (JMS) uses Observer pattern along with Mediator pattern to allow
applications to subscribe and publish data to other applications. Check out Observer
Pattern post for implementation details and example program.

#Strategy Pattern
Strategy pattern is used when we have multiple algorithm for a specific task and client
decides the actual implementation to be used at runtime.
Strategy pattern is also known as Policy Pattern. We defines multiple algorithms and let
client application pass the algorithm to be used as a parameter. One of the best example
of this pattern is Collections.sort() method that takes Comparator parameter. Based on
the different implementations of Comparator interfaces, the Objects are getting sorted in
different ways.

Check out Strategy Pattern post for implementation details and example program.

#Command Pattern
Command Pattern is used to implement lose coupling in a request-response model. In
command pattern, the request is send to the invoker and invoker pass it to the
encapsulated command object. Command object passes the request to the appropriate
method of Receiver to perform the specific action.

Let’s say we want to provide a File System utility with methods to open, write and close
file and it should support multiple operating systems such as Windows and Unix.

To implement our File System utility, first of all we need to create the receiver classes that
will actually do all the work. Since we code in terms of java interfaces, we can have
FileSystemReceiver interface and it’s implementation classes for different operating
system flavors such as Windows, Unix, Solaris etc. Check out Command Pattern post for
the implementation details with example program.

#State Pattern
State design pattern is used when an Object change it’s behavior based on it’s internal
state.

If we have to change the behavior of an object based on it’s state, we can have a state
variable in the Object and use if-else condition block to perform different actions based on
the state. State pattern is used to provide a systematic and lose-coupled way to achieve
this through Context and State implementations.

Check out State Pattern post for implementation details with example program.

#Visitor Pattern
Visitor pattern is used when we have to perform an operation on a group of similar kind of
Objects. With the help of visitor pattern, we can move the operational logic from the
objects to another class.

For example, think of a Shopping cart where we can add different type of items
(Elements), when we click on checkout button, it calculates the total amount to be paid.
Now we can have the calculation logic in item classes or we can move out this logic to
another class using visitor pattern. Let’s implement this in our example of visitor pattern.
Check out Visitor Pattern post for implementation details.

#Interpreter Pattern
is used to defines a grammatical representation for a language and provides an
interpreter to deal with this grammar.
The best example of this pattern is java compiler that interprets the java source code into
byte code that is understandable by JVM. Google Translator is also an example of
interpreter pattern where the input can be in any language and we can get the output
interpreted in another language.

Check out Interpreter Pattern post for example program.

#Iterator Pattern
Iterator pattern in one of the behavioral pattern and it’s used to provide a standard way
to traverse through a group of Objects. Iterator pattern is widely used in Java Collection
Framework where Iterator interface provides methods for traversing through a collection.

Iterator pattern is not only about traversing through a collection, we can provide different
kind of iterators based on our requirements. Iterator pattern hides the actual
implementation of traversal through the collection and client programs just use iterator
methods. Check out Iterator Pattern post for example program and implementation
details.

#Memento Pattern
Memento design pattern is used when we want to save the state of an object so that we
can restore later on. Memento pattern is used to implement this in such a way that the
saved state data of the object is not accessible outside of the object, this protects the
integrity of saved state data.

Memento pattern is implemented with two objects – Originator and Caretaker. Originator
is the object whose state needs to be saved and restored and it uses an inner class to
save the state of Object. The inner class is called Memento and its private, so that it can’t
be accessed from other objects.

Check out Memento Pattern for sample program and implementation details.

That’s all for different design patterns in java, this post intent is to provide an index to
browse all of them easily.

1. Observer Design Pattern:

public interface IObserver {


public void update(String productName);
}

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

public class Customer implements IObserver{

private String customerName;


//private ISubject subject;
@Override
public void update(String productName) {
System.out.println("Hello " + customerName + ", " + productName + " is
now avilable on Amazon.");
}

public String getCustomerName() {


return customerName;
}

public void setCustomerName(String customerName) {


this.customerName = customerName;
}

/*public ISubject getSubject() {


return subject;
}

public void setSubject(ISubject subject) {


this.subject = subject;
}*/

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

public interface ISubject {


public void registerObserver(IObserver o);
public void removeObserver(IObserver o);
public void notifyObserver();
}

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

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

public class Product implements ISubject{

private Set<IObserver> listOfObservers = new HashSet<>();


private String productName;
private boolean available;

@Override
public void registerObserver(IObserver o) {

System.out.println( ((Customer) o).getCustomerName() + " has


registered.");

listOfObservers.add(o);
}
@Override
public void removeObserver(IObserver o) {
listOfObservers.remove(o);
}

@Override
public void notifyObserver() {

System.out.println("Notifying all the customers.");

for (IObserver observer: listOfObservers){


observer.update(productName);
}

public Set<IObserver> getListOfObservers() {


return listOfObservers;
}

public void setListOfObservers(Set<IObserver> listOfObservers) {


this.listOfObservers = listOfObservers;
}

public String getProductName() {


return productName;
}

public void setProductName(String productName) {


this.productName = productName;
}

public boolean isAvailable() {


return available;
}

public void setAvailable(boolean available) {


this.available = available;

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

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

public class TestMain {


public static void main(String[] args) {

Customer cus1 = new Customer();


Customer cus2 = new Customer();

cus1.setCustomerName("Dinesh");
cus2.setCustomerName("Vijay");

Product iphone6 = new Product();


iphone6.setProductName("iPhone6");
iphone6.setAvailable(false);

iphone6.registerObserver(cus1);
iphone6.registerObserver(cus2);

try {

int i = 0;

while (i < 3) {
System.out.println("Waiting..");
Thread.sleep(1000);
++i;
}

} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

iphone6.setAvailable(true);

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

Output:

Dinesh has registered.


Vijay has registered.
Waiting..
Waiting..
Waiting..
Notifying all the customers.
Hello Dinesh, iPhone6 is now avilable on Amazon.
Hello Vijay, iPhone6 is now avilable on Amazon.

__________________________________________________________________________________________
_________________________________________________
2. SINGLETON

This is the most used pattern. A lot of framework already implement this pattern, such as
Spring, CDI (via @ApplicationScoped) or EJBs (using @Singleton). Still, it is nice to know
how to implement it the old way. ;)

public class SingletonSample {


private static SingletonSample instance = null;

private SingletonSample() {
}

public static SingletonSample getInstance() {


if(instance == null) {
instance = new SingletonSample();
}
return instance;
}
}
There is no secret. You need an object that only needs to be instantiate once, so, you can
use a singleton. The class needs to declare a private constructor to prevent people to
instantiate it from outside the class. Also, you need to declare a static field of the type of
the singleton. The method getInstance() assures that only one instance of this class is
created at runtime.
__________________________________________________________________________________________
_________________________________________________

2.1. INITIALIZATION ON DEMAND HOLDER

This pattern is much like the Singleton, but the Initialization on Demand Holder has
critical advantage over the Singleton: It is thread safe.
The getInstance() method from the Singleton pattern is not thread safe, not if you don't
make it synchronized, so, it can be instantiate more than once. If you do make your
method synchronized, you are making your getInstance() method slower than it could be
if it were not.

public class SingletonSample {


private SingletonSample() {
}

public static SingletonSample getInstance() {


return SingletonSampleHolder.INSTANCE;
}

private static class SingletonSampleHolder {


private static final SingletonSample INSTANCE = new SingletonSample();
}
}
As the name says, this type of Singleton does not initialize the instance until the
getInstance() is called, with the advantage that it is thread safe.
Since the JVM does not load the SingletonSampleHolder at startup because there is no
static reference of this class anywhere in the code, the instance is not created until the
first call of the getInstance() method.
This pattern is much like the Singleton, but the Initialization on Demand Holder has
critical advantage over the Singleton: It is thread safe.
The getInstance() method from the Singleton pattern is not thread safe, not if you don't
make it synchronized, so, it can be instantiate more than once. If you do make your
method synchronized, you are making your getInstance() method slower than it could be
if it were not.

public class SingletonSample {


private SingletonSample() {
}

public static SingletonSample getInstance() {


return SingletonSampleHolder.INSTANCE;
}

private static class SingletonSampleHolder {


private static final SingletonSample INSTANCE = new SingletonSample();
}
}
As the name says, this type of Singleton does not initialize the instance until the
getInstance() is called, with the advantage that it is thread safe.
Since the JVM does not load the SingletonSampleHolder at startup because there is no
static reference of this class anywhere in the code, the instance is not created until the
first call of the getInstance() method.

__________________________________________________________________________________________
_________________________________________________

3. THE STRATEGY AND THE FACTORY PATTERN

Both are well-known design patterns. For sure two of the most useful design patterns,
specially using them together.
When both are combined, you can create objects from a given qualifier. The example is
right below:

public interface Building {


String getType();
}
public class House implements Building {
public String getType(){
return "house"
}
}
public class Edifice implements Building {
public String getType(){
return "edifice"
}
}
public class BuildingFactory {
private static Map<String, Building> instances;
static {
instances = new HashMap<>();

instances.put("house", new House());


instances.put("edifice", new Edifice());
}

public static <T extends Building> T getBuilding(String type){


return (T) instances.get(type);
}
}
Building building = BuildingFactory.getBuilding("house");
If you need a specific building, you need just to give a building type and one will be
returned, or null there is no instance for this type. Very useful, besides, it gives us a
chance to use the most of polymorphism.

__________________________________________________________________________________________
_________________________________________________
4. FLUENT BUILDER

Some objects require lots of parameters to be created. In this case, either using the
constructor to create this object or using the setters will make our code ugly and hard to
understand.

The builder pattern can help us in this case.

public class Product {


private String id;
private String name;
private String description;
private Double value;

private Product(Builder builder) {


setId(builder.id);
setName(builder.name);
setDescription(builder.description);
setValue(builder.value);
}

public static Builder newProduct() {


return new Builder();
}

public String getId() {


return id;
}

public void setId(String id) {


this.id = id;
}
public String getName() {
return name;
}

public void setName(String name) {


this.name = name;
}

public String getDescription() {


return description;
}

public void setDescription(String description) {


this.description = description;
}

public Double getValue() {


return value;
}

public void setValue(Double value) {


this.value = value;
}

public static final class Builder {


private String id;
private String name;
private String description;
private Double value;

private Builder() {
}

public Builder id(String id) {


this.id = id;
return this;
}

public Builder name(String name) {


this.name = name;
return this;
}

public Builder description(String description) {


this.description = description;
return this;
}

public Builder value(Double value) {


this.value = value;
return this;
}
public Product build() {
return new Product(this);
}
}
}
Product product = Product.newProduct()
.id(1l)
.description("TV 46'")
.value(2000.00)
.name("TV 46'")
.build();
Okay, this class is not that big and it does not have a lot of fields, but, this is just for an
example, so... :P

__________________________________________________________________________________________
_________________________________________________
5. CHAIN OF RESPONSIBILITY

You always need to build applications which require a lot of business logic. Behind this
much of logic, there is always high complexity. This high complexity makes our code
harder to understand, as well as harder to track, to log and so on.
The CoR pattern makes us break our code into little pieces and organize them into
sequential steps.

public interface Command<T>{


boolean execute(T context);
}

public class FirstCommand implements Command<Map<String, Object>>{


public boolean execute(Map<String, Object> context){
//doing something in here
}
}

public class SecondCommand implements Command<Map<String, Object>>{


public boolean execute(Map<String, Object> context){
//doing something in here
}
}

public class Chain {


public List<Command> commands;

public Chain(Command... commands){


this.commands = Arrays.asList(commands);
}

public void start(Object context){


for(Command command : commands){
boolean shouldStop = command.execute(context);
if(shouldStop){
return;
}
}
}
}
Chain chain = new Chain(new FirstCommand(), new SecondCommand());
Map<String, Object> context = new HashMap<>();
context.put("some parameter", "some value");
chain.start(context);
Now we can break our code into Commands and separate each logic in just one place.
Also, we can reorganize as we want, making our code more decoupled, thus solving our
complexity problem.
__________________________________________________________________________________________
_________________________________________________

6. TEMPLATE METHOD

This pattern defines a skeleton in a method for an operation. It is very useful when your
have common method calls but different behaviors. This pattern is totally based in
polymorphism.

public abstract class Animal {


public abstract void makeSound();
public abstract void eatFood();
public abstract void sleep();

public void doEveryday(){


makeSound();
eatFood();
sleep();
}
}
public class Dog extends Animal {
public void makeSound(){
//bark!
}

public void eatFood(){


//eat dog food
}

public void sleep(){


//sleep just a little bit
}
}
__________________________________________________________________________________________
_________________________________________________

7. STATE PATTERN
A lot of objects have states. For example, a radio. A radio have basically two states: on
and off. Can we represent this in object oriented programming? Well, yes:

public class Radio {


private boolean on;
private RadioState state;

public Radio(RadioState state){


this.state = state;
}

public void execute(){


state.execute(this);
}

public void setState(RadioState state){


this.state = state;
}

public void setOn(boolean on){


this.on = on;
}

public boolean isOn(){


return on;
}

public boolean isOff(){


return !on;
}
}
public interface RadioState {
void execute(Radio radio);
}
public class OnRadioState implements RadioState {
public void execute(Radio radio){
//throws exception if radio is already on
radio.setOn(true);
}
}
public class OffRadioState implements RadioState {
public void execute(Radio radio){
//throws exception if radio is already off
radio.setOn(false);
}
}
Radio radio = new Radio(new OffRadioState()); //initial status
radio.setState(new OnRadioState());
radio.execute(); //radio on
radio.setState(new OffRadioState());
radio.execute(); //radio off
This is just a simple example, but, when we talk about an object that have a lot of states,
this control can help a lot. You can define rules to create final states and states that
requires an previous state to be executed. For example, in this radio scenario, you can
only turn a radio off if the radio is on, otherwise an exception will be thrown. Basically you
can do whatever the business tell you to do.

__________________________________________________________________________________________
_________________________________________________
8. Callback Pattern:

Asynchronous and Synchronous Callbacks in Java

CallBack Function is a function which passed into another


function as an argument and is expected to execute after some kind of event.
The purpose of the callback is to inform a class Sync/Async if some work in other class is
done.
This is very useful when working with Asynchronous tasks.
Suppose we want to perform some routine tasks like perform some operation or display
content after
some clicking a button, or fetching data from internet.
This is also used in event handling, as we get notified when a button clicked via callback
function.

This type of design pattern is used in Observer Design Pattern.


The observer pattern is a software design pattern in which an object,
called the subject, maintains a list of its dependent, called observers,
and notifies them automatically of any state changes, usually by calling one of their
methods( Source:wiki).

In Java, Callbacks can be implemented using interface.


The general procedure for implementation is given below.

1. Define the methods in an interface that we want to invoke after callback.


2. Define a class that will implement the callback methods of the interface.
3. Define a reference in other class to register the callback interface.
4. Use that reference to invoke the callback method.

# Synchronous Callback:
The code execution will block or wait for the event before continuing.
Until your event returns a response your program will not execute any further.
So Basically the callback performs all its work before returning to the call statement.
The problem with synchronous callback is that they appear to lag.

# Asynchronous Callback:
An Asynchronous call do not block the program from the code execution.
when the call returns from the event the call returns back to the callback function.
So in the context of java we have to Create a new thread invoke the callback method
inside that thread.
Callback may be invoked from a thread but is not a requirement. A Callback may also
start a new thread
thus making themselves asynchronous.
package com.anurag.example.callback;

//Java program to illustrate Asynchronous callback

interface ClickHandler {
void onClick();
}

class Button {

private ClickHandler clickHandler; // listener field

// setting the listener


public void addClickHandler(ClickHandler onClickHandler) {
this.clickHandler = onClickHandler;
}

// My Asynchronous task
//To make it Synchronous just remove new Thread Part.
public void click() {

// An Async task always executes in new thread


new Thread(new Runnable() {
public void run() {
if (clickHandler != null) {
clickHandler.onClick();
}
}
}).start();
}
}

public class AsynchronousCallbackTest {

// Driver Program
public static void main(String[] args) {

Button btn = new Button();


btn.addClickHandler(new ClickHandler() {

@Override
public void onClick() {

System.out.println("Button is clicked.");

}
});
btn.click();

System.out.println("A statement after 'btn.click()' statement, "


+ "just to demonstrate it's async nature");
}
}

__________________________________________________________________________________________
_________________________________________________
9. Prototype Design 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.

Prototype pattern provides a mechanism to copy the original object to a new object and
then modify it according to our needs.
Prototype design pattern uses java cloning to copy the object.

package com.anurag.example.prototype;

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

public class Employees implements Cloneable {

private List<String> empList;

public Employees() {
empList = new ArrayList<String>();
}

public Employees(List<String> list) {


this.empList = list;
}

public void loadData() {


// read all employees from database and put into the list
empList.add("Pankaj");
empList.add("Raj");
empList.add("David");
empList.add("Lisa");
}

public List<String> getEmpList() {


return empList;
}

// Notice that the clone method is overridden to provide a deep copy of the
// employees list.
@Override
public Object clone() throws CloneNotSupportedException {
List<String> temp = new ArrayList<String>();
for (String s : this.getEmpList()) {
temp.add(s);
}
return new Employees(temp);
}

---------
package com.anurag.example.prototype;

import java.util.List;

public class PrototypePatternTest {

public static void main(String[] args) throws CloneNotSupportedException {


Employees emps = new Employees();
emps.loadData();

// Use the clone method to get the Employee object


Employees empsNew = (Employees) emps.clone();
Employees empsNew1 = (Employees) emps.clone();
List<String> list = empsNew.getEmpList();
list.add("John");
List<String> list1 = empsNew1.getEmpList();
list1.remove("Pankaj");

System.out.println("emps List: " + emps.getEmpList());


System.out.println("empsNew List: " + list);
System.out.println("empsNew1 List: " + list1);
}

-----
If the object cloning was not provided, we will have to make database call to fetch the
employee list every time. Then do the manipulations that would have been resource and
time consuming.

That’s all for prototype design pattern in java.

__________________________________________________________________________________________
_________________________________________________
__________________________________________________________________________________________
_________________________________________________
10. Memento design pattern

Memento design pattern is one of the behavioral design pattern. Memento design pattern
is used when we want to save the state of an
object so that we can restore later on. Memento pattern is used to implement this in such
a
way that the saved state data of the object is not accessible outside of the object, this
protects the integrity of saved state data.

Memento design pattern is implemented with two objects – Originator and Caretaker.

Originator is the object whose state needs to be saved and restored and it uses an inner
class to save the state of Object. The inner class is called Memento and it’s private, so
that it can’t be accessed from other objects.

Caretaker is the helper class that is responsible for storing and restoring the Originator’s
state through Memento object.
Since Memento is private to Originator, Caretaker can’t access it and it’s stored as an
Object within the caretaker.
Memento Design Pattern Java
One of the best real life example is the text editors where we can save it’s data anytime
and use undo to restore it to previous saved state.

We will implement the same feature and provide a utility where we can write and save
contents to a File anytime and we
can restore it to last saved state. For simplicity, I will not use any IO operations to write
data into file.

Memento pattern is simple and easy to implement, one of the thing needs to take care is
that Memento class should be accessible
only to the Originator object. Also in client application, we should use caretaker object for
saving and restoring the originator state.

Also if Originator object has properties that are not immutable, we should use deep copy
or cloning to avoid data integrity issue like
I have used in above example. We can use Serialization to achieve memento pattern
implementation that is more generic rather than Memento
pattern where every object needs to have it’s own Memento class implementation.

One of the drawback is that if Originator object is very huge then Memento object size
will also be huge and use a lot of memory.

---------
package com.anurag.example.Memento;

public class FileWriterCaretaker {

private Object obj;

public void save(FileWriterUtil fileWriter) {


this.obj = fileWriter.save();
}

public void undo(FileWriterUtil fileWriter) {


fileWriter.undoToLastSave(obj);
}
}

---------
package com.anurag.example.Memento;

public class FileWriterClient {

public static void main(String[] args) {

FileWriterCaretaker caretaker = new FileWriterCaretaker();

FileWriterUtil fileWriter = new FileWriterUtil("data.txt");


fileWriter.write("First Set of Data\n");
System.out.println(fileWriter+"\n\n");

// lets save the file


caretaker.save(fileWriter);
//now write something else
fileWriter.write("Second Set of Data\n");

//checking file contents


System.out.println(fileWriter+"\n\n");

//lets undo to last save


caretaker.undo(fileWriter);

//checking file content again


System.out.println(fileWriter+"\n\n");

----------
package com.anurag.example.Memento;

public class FileWriterUtil {

private String fileName;


private StringBuilder content;

public FileWriterUtil(String file) {


this.fileName = file;
this.content = new StringBuilder();
}

@Override
public String toString() {
return this.content.toString();
}

public void write(String str) {


content.append(str);
}

public Memento save() {


return new Memento(this.fileName, this.content);
}

public void undoToLastSave(Object obj) {


Memento memento = (Memento) obj;
this.fileName = memento.fileName;
this.content = memento.content;
}
private class Memento {
private String fileName;
private StringBuilder content;

public Memento(String file, StringBuilder content) {


this.fileName = file;
// notice the deep copy so that Memento and FileWriterUtil content
// variables don't refer to same object
this.content = new StringBuilder(content);
}
}
}

__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________
__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________

__________________________________________________________________________________________
_________________________________________________

You might also like