Designpatternsinjava 171112205304 PDF
Designpatternsinjava 171112205304 PDF
DESIGN PATTERN
Usage of Factory
Design Pattern
When a class doesn't When a class wants When the parent
know what sub-classes that its sub-classes classes choose the
will be required to specify the objects creation of objects
create to be created. to its sub-classes.
Plan Abstract Class
1. import java.io.*;
2. abstract class Plan{
3. protected double rate;
4. abstract void getRate();
5.
6. public void calculateBill(int units){
7. System.out.println(units*rate);
8. }
9. }//end of Plan class.
Subclasses
1. class DomesticPlan extends Plan{ 1. class CommercialPlan extends 1. class InstitutionalPlan extends Plan{
5. } 4. rate=7.50; 5. }
4. if(planType == null){
5. return null;
6. }
7. if(planType.equalsIgnoreCase("DOMESTICPLAN")) {
9. }
12. }
15. }
17. }
2. class GenerateBill{
5. System.out.print("Enter the name of plan for which the bill will be generated: ");
7.
8. String planName=br.readLine();
11.
15. p.getRate();
16. p.calculateBill(units);
17. }
DESIGN PATTERN
Intent
Provide an interface for creating families of related or dependent
objects without specifying their concrete classes.
Usage
● When a system should be independent of how its products are created,
composed, and represented.
● When a system should be configured with one of multiple families of
products.
● When a family of related product objects is designed to be used
together, and you need to enforce this constraint.
● When you want to provide a class library of products, and you want to
reveal just their interfaces, not their implementations.
WidgetFactory abstract class
public abstract class WidgetFactory{
...
}
WidgetFactory imlpementing classes
public class PMWidgetFactory extends WidgetFactory{ public class MotifWidgetFactory extends WidgetFactory{
}; };
} }
} }
Window with its imlpementing classes
public abstract class Window{ public class MotifWindow extends Window{
}
ScrollBar with its imlpementing classes
public abstract class ScrollBar{ public class MotifScrollBar extends ScrollBar{
}
SINGLETON
DESIGN PATTERN
Singleton Pattern says that just "define a
class that has only one instance and provides a
global point of access to it".
again.
initialization
private static StaticBlockSingleton instance;
private StaticBlockSingleton(){}
}
Bill Pugh Singleton Implementation
public class BillPughSingleton {
DESIGN PATTERN
Concept
● GoF Definition: Specify the kinds of objects to create
using a prototypical instance, and create new objects
by copying this prototype.
● The prototype pattern provides an alternative method
for instantiating new objects by copying or cloning an
instance of an existing one. Creating a new instance,
in a real-world scenario, is normally treated as an
expensive operation.
Examples
● Suppose we have a master copy of a valuable document.
We want to make some change to it to get a different
feel. We can make a photocopy of this document and then
try to edit our changes.
● Suppose we have made an application. The next time we
want to create a similar application with somesmall
changes, we must start with a copy from our master copy
application and make the changes. We’ll not start from
the scratch.
BaseCar.class
public abstract class BasicCar implements Cloneable{
public String modelname;
public int price;
public String getModelname(){
return modelname;
}
public void setModelname(String modelname){
this.modelname = modelname;
}
public static int setPrice(){
int price = 0;
Random r = new Random();
int p = r.nextInt(100000);
price = p;
return price;
}
public BasicCar clone() throws CloneNotSupportedException{
return (BasicCar)super.clone();
}
}
Ford.class & Nano.class
public class Ford extends BasicCar public class Nano extends BasicCar{
{ public Nano(String m){
public Ford(String m){ modelname = m;
modelname = m; }
} @Override
@Override public BasicCar clone() throws
public BasicCar clone() throws CloneNotSupportedException{
CloneNotSupportedException{ return (Nano)super.clone();
return (Ford)super.clone(); }
} }
}
PrototypePatternEx.class
public class PrototypePatternEx{
public static void main(String[] args) throws CloneNotSupportedException{
System.out.println("***Prototype Pattern Demo***\n");
BasicCar nano_base = new Nano("Green Nano");
nano_base.price=100000;
BasicCar ford_basic = new Ford("Ford Yellow");
ford_basic.price=500000;
BasicCar bc1;
//Clone Nano Object
bc1 =nano_base.clone();
//Price will be more than 100000 for sure
bc1.price = nano_base.price+BasicCar.setPrice();
System.out.println("Car is: "+ bc1.modelname+" and it's price is Rs."+bc1.price);
//Clone Ford Object
bc1 =ford_basic.clone();
//Price will be more than 500000 for sure
bc1.price = ford_basic.price+BasicCar.setPrice();
System.out.println("Car is: "+ bc1.modelname+" and it's price is Rs."+bc1.price);
}
}
WHEN TO USE
● When the system does not care about the creational
mechanism of the products,this pattern is very helpful.
● We can use this pattern when we need to instantiate
classes at runtime.
● In our example, we have used the default clone() method
in Java, which is a shallow copy. Thus, it is
inexpensive compared to a deep copy.
What are the advantages of the prototype pattern?
● We can include or discard products at runtime.
● We can create new instances with a cheaper cost.
What are the disadvantages of the prototype pattern?
● Each subclass has to implement the cloning mechanism.
● Implementing the cloning mechanism can be challenging
if the objects under consideration do not support
copying or if there is any kind of circular reference.
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.
3. }
Create 2 implementation classes of Company: Sony and Samsung
ArrayList<Packing>(); }
packs.price();
}
Create the CDBuilder class Create the BuilderDemo class
6. } 6.
9. cds.addItem(new Samsung()); 9. }
11. }
12. }
let’s assume, our User object has following 5 attributes i.e. firstName, lastName, age, phone and address.
In normal practice, if you want to make a immutable User class, then you must pass all five information as parameters to
constructor. It will look like this:
public User (String firstName, String lastName, int age, String phone, String address){
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.phone = phone;
this.address = address;
}
Very good. Now what if only firstName and lastName are mandatory and rest 3 fields are optional. Problem !! We need more
constructors.
public User (String firstName, String lastName, int age, String phone){ ... }
public User (String firstName, String lastName, String phone, String address){ ... }
We will need some more like above. Still can manage? Now let’s introduce our sixth attribute i.e. salary. Now it is problem.
One way it to create more constructors, and another is to loose the immutability and introduce setter methods. You choose any of
both options, you loose something, right?
Here, builder pattern will help you to consume additional attributes while retaining the immutability of Use class.
//All getter, and NO setter to provde immutability
public class User
public String getFirstName() {
{ return firstName;
//All final attributes }
public String getLastName() {
private final String firstName; // required
return lastName;
private final String lastName; // required }
private final int age; // optional public int getAge() {
return age;
private final String phone; // optional
}
private final String address; // optional public String getPhone() {
return phone;
}
private User(UserBuilder builder) { public String getAddress() {
this.firstName = builder.firstName; return address;
this.lastName = builder.lastName; }
DESIGN PATTERN
Mostly, performance is the key issue during the software development and the object creation, which
may be a costly step.
Object Pool Pattern says that " to reuse the object that are expensive to create".
Basically, an Object pool is a container which contains a specified amount of objects. When an object is
taken from the pool, it is not available in the pool until it is put back. Objects in the pool have a
lifecycle: creation, validation and destroy.
A pool helps to manage available resources in a better way. There are many using examples: especially
in application servers there are data source pools, thread pools etc.
Advantage of Object Pool design pattern
● It boosts the performance of the application significantly.
● It is most effective in a situation where the rate of initializing a class instance is high.
● It manages the connections and provides a way to reuse and share them.
● It can also provide the limit for the maximum number of objects that can be created.
Usage:
● When an application requires objects which are expensive to create. Eg: there is a need of opening too
many connections for the database then it takes too longer to create a new one and the database server
will be overloaded.
● When there are several clients who need the same resource at different times.
NOTE: Object pool design pattern is essentially used in Web Container of the server for creating thread pools and data source
pools to process the requests.
Object pool
public abstract class ObjectPool<T> {
private Set<T> available = new HashSet<>();
private Set<T> inUse = new HashSet<>();
protected abstract T create();
/**
* Checkout object from pool
*/
public synchronized T checkOut() {
if (available.isEmpty()) {
available.add(create());
}
T instance = available.iterator().next();
available.remove(instance);
inUse.add(instance);
return instance;
}
public class Oliphaunt {
public synchronized void checkIn(T instance) {
private static int counter = 1;
inUse.remove(instance);
private final int id;
available.add(instance);
}
public Oliphaunt() {
id = counter++;
try {
@Override
Thread.sleep(1000);
public synchronized String toString() {
} catch (InterruptedException e) {
return String.format("Pool available=%d inUse=%d",
e.printStackTrace();
available.size(), inUse.size());
}
}
}
}
public int getId() {
return id;
}
@Override
public String toString() {
return String.format("Oliphaunt id=%d", id);
}
}
public class App {
public class OliphauntPool extends ObjectPool<Oliphaunt> { public static void main(String[] args) {
OliphauntPool pool = new OliphauntPool();
LOGGER.info(pool.toString());
@Override Oliphaunt oliphaunt1 = pool.checkOut();
LOGGER.info("Checked out {}", oliphaunt1);
protected Oliphaunt create() {
LOGGER.info(pool.toString());
return new Oliphaunt();
Oliphaunt oliphaunt2 = pool.checkOut();
} LOGGER.info("Checked out {}", oliphaunt2);
} Oliphaunt oliphaunt3 = pool.checkOut();
LOGGER.info("Checked out {}", oliphaunt3);
LOGGER.info(pool.toString());
LOGGER.info("Checking in {}", oliphaunt1);
pool.checkIn(oliphaunt1);
LOGGER.info("Checking in {}", oliphaunt2);
pool.checkIn(oliphaunt2);
LOGGER.info(pool.toString());
Oliphaunt oliphaunt4 = pool.checkOut();
LOGGER.info("Checked out {}", oliphaunt4);
Oliphaunt oliphaunt5 = pool.checkOut();
LOGGER.info("Checked out {}", oliphaunt5);
LOGGER.info(pool.toString());
}
}
Structural design patterns
ADAPTER
DESIGN PATTERN
Adapter(Wrapper)
An Adapter Pattern says that just "converts the interface of a class into another interface that a
client wants"
● 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.
UML for Adapter pattern
● Target Interface: This is the desired interface class which will be used by the clients.
● Adapter class: This class is a wrapper class which implements the desired target interface and modifies the
specific request available from the Adaptee class.
● Adaptee class: This is the class which is used by the Adapter class to reuse the existing functionality and modify
them for desired use.
● Client: This class will interact with the Adapter class.
targetInterface.giveBankDetails();
System.out.print(targetInterface.getCreditCard());
}
BRIDGE
DESIGN PATTERN
Bridge
Decouple an abstraction from its implementation so that the two can vary independently
● 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.
First, we have our TV implementation //Concrete Implementor
interface: public class Sony implements TV {
implementor.tuneChannel(channel);
}
}
As the remote control holds a reference to the TV, it can delegates the methods through to the interface. But
what is we want a more specific remote control - one that has the + / - buttons for moving through the
channels? All we need to do is extend our RemoteControl abstraction to contain these concepts:
}
public class Pentagon extends Shape{
public class RedColor implements Color{
public Pentagon(Color c) {
public void applyColor(){
super(c);
System.out.println("red.");
}
}
}
@Override
public void applyColor() {
System.out.print("Pentagon
filled with color ");
public class GreenColor implements
color.applyColor();
Color{
}
}
COMPOSITE
DESIGN PATTERN
Advantage of Composite Design 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".
● It defines class hierarchies that contain primitive and complex objects.
● Implements default behavior for the interface common to all classes as appropriate.
2) Leaf
● Represents leaf objects in composition. A leaf has no children.
4) Client
● Manipulates objects in the composition through the component interface.
Example
@Override
public void draw(String fillColor) {
System.out.println("Drawing Triangle with color "+fillColor);
}
}
Example
@Override
public void draw(String fillColor) {
System.out.println("Drawing Circle with color "+fillColor);
}
}
Example
//adding shape to drawing
public void add(Shape s){
this.shapes.add(s);
}
4) Client
● Manipulates objects in the composition through the component interface.
DECORATE
DESIGN PATTERN
Concept
● GoF Definition: Attach additional responsibilities to an object dynamically.Decorators
● This main principle of this pattern says that we cannot modify existing functionalities
but we can extend them. In other words, this pattern is open for extension but closed
for modification.
● The core concept applies when we want to add some specific functionalities to some
DESIGN PATTERN
Concept
● GoF Definition: Provide a unified interface to a set of interfaces in a system. Facade
defines a higher-level interface that makes the subsystem easier to use.
● Fasade emphasize the abstraction and hide the complex details by exposing a simple
interface.
Examples
● Suppose you are going to organize a birthday party and you have invited 100 people.
Nowadays, you can go to any party organizer and let him/her know the minimum
information— (party type, date and time of the party, number of attendees, etc.). The
organizer will do the rest for you. You do not even think about how he will decorate the
party room, whether people will take food from self-help counter or will be served by a
caterer, and so on.
● We can think about a case where we use a method from a library. The user doesn’t care
how the method is implemented in the library. He/she just calls the method to serve
his/her easy purpose. The pattern can be best described by the example that follows.
public class RobotBody{ public class RobotFacade{
RobotColor rc;
public void CreateBody(){
RobotMetal rm ;
System.out.println("Body RobotBody rb;
Creation done"); public RobotFacade(){
}} rc = new RobotColor();
rm = new RobotMetal();
public class RobotColor{
rb = new RobotBody();
private String color;
}
public void SetColor(String color){
public void ConstructRobot(String color,String metal){
this.color = color;
System.out.println("\nCreation of the Robot
System.out.println("Color is set to : Start");
"+ this.color);
rc.SetColor(color);
}
rm.SetMetal(metal);
}
rb.CreateBody();
System.out.println(" \nRobot Creation End");
public class RobotMetal{ System.out.println();
private String metal; }}
public void SetMetal(String metal){ class FacadePatternEx{
this.metal=metal; public static void main(String[] args){
System.out.println("Metal is set to : System.out.println("***Facade Pattern Demo***");
"+this.metal); RobotFacade rf1 = new RobotFacade();
} rf1.ConstructRobot("Green", "Iron");
} RobotFacade rf2 = new RobotFacade();
rf2.ConstructRobot("Blue", "Steel");
}
}
Note
● We use Facade pattern to represent a simple interface instead of a complex subsystem.
● Here we promote weak coupling among subsystems—so, in this way, we are making them
portable.
● We already mentioned that we separate subsystems from clients by a simple interface.
With this model, we not only make the system easier to use but also reduce the number of
objects that the clients need to deal with.
● There is truly no major disadvantage associated with this pattern. On the other hand, it
has proven its usefulness in libraries like jQuery also.
FLYWEIGHT
DESIGN PATTERN
Flyweight pattern is primarily used to reduce the number of objects created and to decrease memory footprint and increase
performance.Flyweight pattern tries to reuse already existing similar kind objects by storing them and creates new object
when no matching object is found
● Flyweight pattern introduces complexity and if number of shared objects are huge then there is a
trade of between memory and time, so we need to use it judiciously based on our requirements.
● Flyweight pattern implementation is not useful when the number of intrinsic properties of Object is
huge.
public interface Shape { public class ShapeFactory {
void draw(); private static final HashMap<String, Shape> circleMap =
} new HashMap();
public class Circle implements Shape { public static Shape getCircle(String color) {
private String color; Circle circle = (Circle)circleMap.get(color);
private int x;
private int y; if(circle == null) {
private int radius; circle = new Circle(color);
public Circle(String color){ circleMap.put(color, circle);
this.color = color; System.out.println("Creating circle of color : " +
} color);
public void setX(int x) { }
this.x = x; return circle;
} }
public void setY(int y) { }
this.y = y;
} public class FlyweightPatternDemo {
public void setRadius(int radius) { private static final String colors[] = { "Red", "Green",
this.radius = radius; "Blue", "White", "Black" };
} public static void main(String[] args) {
@Override for(int i=0; i < 20; ++i) {
public void draw() { Circle circle =
System.out.println("Circle: Draw() [Color : (Circle)ShapeFactory.getCircle(getRandomColor());
" + color + ", x : " + x + ", y :" + y + ", radius circle.setX(getRandomX());
:" + radius); circle.setY(getRandomY());
} circle.setRadius(100);
} circle.draw();
} }
}
PROXY
DESIGN PATTERN
Concept
Proxy pattern intent is to “Provide a surrogate or
placeholder for another object to control access to
it”.
Usage
● It can be used in Virtual Proxy scenario---Consider a situation where there is
verify that whether the actual user has access the appropriate content or not.
● It can be used in Remote Proxy scenario---A remote proxy can be thought about the stub
● It can be used in Smart Proxy scenario---A smart proxy provides additional layer of
}
OutPut
Package java.rmi
Behavioral Design Patterns
CHAIN OF RESPONSIBILITY
DESIGN PATTERN
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.
Advantage
Usage
● 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.
UML for Chain of Responsibility Pattern:
Example of Chain of Responsibility Pattern
class Money { abstract class NoteModule{
private int amt;
protected NoteModule next;
public Money(int amt) { abstract void takeMoney(Money money);
setAmt(amt) public void setNextMoneyModule(NoteModule next) {
} this.next = next;
}
public int getAmt() {
return amt; }
}
@Override @Override
} }
if(remind > 0 && next != null){ if(remind > 0 && next != null){
} }
} }
} }
class NoteModule10000 extends NoteModule{ class NoteModule20000 extends NoteModule{
@Override @Override
} }
if(remind > 0 && next != null){ if(remind > 0 && next != null){
} } } }
} }
public class BankomatApp {
note20000.setNextMoneyModule(note10000);
note10000.setNextMoneyModule(note5000);
note5000.setNextMoneyModule(note1000);
note20000.takeMoney(new Money(117_000));
}
OutPut
117_000 117_100
5 - 20000 Error
1 - 10000
1 - 5000
2 - 1000
Chain of Responsibility Pattern Examples in JDK
● java.util.logging.Logger#log()
● javax.servlet.Filter#doFilter()
Pitfalls
● Handling/handler guarantee
● Runtime configuration risk
● Chain length performance issues
Chain of Responsibility Summary
DESIGN PATTERN
Command pattern is a data driven design pattern and falls
under behavioral pattern category.
A Command Pattern says that "encapsulate a request under an object as a command and pass it to invoker
object. Invoker object looks for the appropriate object which can handle this command and pass the
command to the corresponding object and that object executes the command".
● It separates the object that invokes the operation from the object that actually performs the operation
● It makes easy to add new commands, because existing classes remain unchanged.
Usage of command pattern
● A history of requests is needed.
● You need callback functionality.
● Requests need to be handled at variant times or in variant orders.
● The invoker should be decoupled from the object handling the invocation.
//Command
public interface Command{
public void execute();
}
//Concrete Command
//Concrete Command
public class LightOffCommand implements
public class LightOnCommand implements
Command{
Command{
//reference to the light
//reference to the light
Light light;
Light light;
public LightOffCommand(Light light){
public LightOnCommand(Light light){
this.light = light;
this.light = light;
}
}
public void execute(){
public void execute(){
light.switchOff();
light.switchOn();
}
}
}
}
//Receiver
public class Light{ //Client
private boolean on; public class Client{
public void switchOn(){ public static void main(String[] args) {
on = true; RemoteControl control = new RemoteControl();
} Light light = new Light();
public void switchOff(){ Command lightsOn = new LightsOnCommand(light);
on = false; Command lightsOff = new LightsOffCommand(light);
} //switch on
} control.setCommand(lightsOn);
control.pressButton();
//Invoker
//switch off
public class RemoteControl{
control.setCommand(lightsOff);
private Command command;
control.pressButton();
public void setCommand(Command command){
}
this.command = command;
}
}
public void pressButton(){
command.execute();
}
}
Watch Out for the Downsides
This pattern ends up forcing a lot of Command classes that will make your design look cluttered -
more operations being made possible leads to more command classes. Intelligence required of
which Command to use and when leads to possible maintenance issues for the central controller.
INTERPRETER
DESIGN PATTERN
Definition: Given a language, define a representation for its grammar along with an
interpreter that uses the representation to interpret sentences in the language.
Concept
Real–Life Example
A language translator who translates a language for us provides a classic example for this
pattern. Or, we can also consider music notes as our grammar and musicians as our
interpreters.
A Java compiler interprets the source code into bytecode. This byte code is understandable
by JVM (Java virtual machine). In C# also, our source code is converted to MSIL (Microsoft
intermediate language) code, which is interpreted by CLR (common language runtime). Upon
execution, this MSIL (intermediate code) is converted to native code (binary executable
code) by a JIT (Just In time) compiler.
Implementation
class Context{
public String input; class StringToBinayExp implements IExpression {
public Context(String input){ private String str;
this.input=input;
} public StringToBinaryExp(String s) {
public void getBinaryForm(String input){ str = s;
int i = Integer.parseInt(input); }
//integer to its equivalent binary string representation
String binaryString = Integer.toBinaryString(i); @Override public void interpret(Context ic) {
System.out.println("Binary equivalent of "+input+ " is "+ binaryString); ic.getBinaryForm(str);
} }
}
public void printInWords(String input) {
this.input = input;
System.out.println("Printing the input in words:"); class IntToWords implements IExpression {
char c[]=input.toCharArray();
for(int i=0;i<c.length;i++){
switch (c[i]) private String str;
{ public IntToWords(String str) {
case '1': this.str = str;
System.out.print("One "); }
Break;
... @Override public void interpret(Context ic) {
case '0': ic.printInWords(str);
System.out.print("Zero "); }
break;
default:
System.out.print("* "); }
break;
}} }}
class InterpreterPatternEx {
public Context clientContext=null;
public IExpression exp=null;
public InterpreterPatternEx(Context c) {
clientContext = c;
}
DESIGN PATTERN
Definition
● GoF Definition: Provide a way to access the elements of an aggregate
object sequentially without exposing its underlying representation.
● Iterators are generally used to traverse a container to access its
elements.
Examples
1. Suppose there are two companies: Company Monitis and TV B. Company Monitis
stores its employee records(name, etc.) in a linked list and Company B stores
its employee data in a big array. One day the two companies decide to work
together. The iterator pattern is handy in such a situation. We need not write
codes from scratch. We’ll have a common interface through which we can access
data for both companies.We’ll simply call the same methods without rewriting the
codes.
2. in a college, the arts department may use array data structure and the science
department may use linked list data structure to store their students’ records.
The main administrative department will access those data through the common
methods—it doesn’t care which data structure is used by individual departments.
UML
public interface IIterator{
public interface ISubject{
void First();//Reset to first element
public IIterator CreateIterator();
String Next();//get next element
}
Boolean IsDone();//End of collection check
public class Arts implements ISubject{ String CurrentItem();//Retrieve Current Item
private String[] subjects; }
public class ArtsIterator implements IIterator{
public Arts(){
private String[] subjects;
subjects = new String[2];
private int position;
subjects[0] = "Bengali";
public ArtsIterator(String[] subjects){
subjects[1] = "English" ;
this.subjects = subjects;
}
position = 0;
public IIterator CreateIterator(){
}
return new ArtsIterator(subjects);
public void First(){
}
position = 0;
}
public String Next(){
return subjects[position++];
}
public Boolean IsDone(){
return position >= subjects.length;
}
public String CurrentItem(){
return subjects[position];
}}}
public class Science implements ISubject{
public class ScienceIterator implements IIterator{
private LinkedList<String> subjects;
private LinkedList<String> subjects;
public Science()
private int position;
{
public ScienceIterator(LinkedList<String> subjects){
subjects = new LinkedList<String>();
this.subjects = subjects;
subjects.addLast("Maths");
position = 0;
subjects.addLast("Comp. Sc.");
}
subjects.addLast("Physics");
public void First(){
}
position = 0;
@Override
}
public IIterator CreateIterator(){
public String Next(){
return new
return subjects.get(position++);
ScienceIterator(subjects);
}
}
public Boolean IsDone(){
}
return position >= subjects.size();
}
public String CurrentItem(){
return subjects.get(position);
}
}
}
class IteratorPatternEx{
public static void main(String[] args){
System.out.println("***Iterator Pattern Demo***\n");
ISubject Sc_subject = new Science();
ISubject Ar_subjects = new Arts();
}
}
MEDIATOR
DESIGN PATTERN
Intent
Define an object that encapsulates how a set of objects interacts. The mediator
pattern promotes loose coupling by keeping objects from referring to each other
explicitly, and it lets you vary their interaction independently.
Problem
Object-oriented design encourages the distribution of behavior among objects.
Such distribution can result in an object structure with many connections
between objects; in the worst case, every object ends up knowing about every
other
Real-life example: Air traffic control
● The pilots of the planes
approaching or departing the
terminal area communicate with
the tower rather than explicitly
communicating with one another.
● The constraints on who can take
off or land are enforced by the
tower.
● It is important to note that the
tower does not control the whole
flight. It exists only to
enforce constraints in the
terminal area.
Computer-world example: GUI dialog box
● A button gets disabled when a certain
entry field is empty.
● Selecting an entry in a list of choices
called a list box might change the
contents of an entry field.
● Conversely, typing text into the entry
field might automatically select one or
more corresponding entries in the list
box.
● Once text appears in the entryfield,
other buttons may become enabled that
let the user do something with the text,
such as changing or deleting the thing
to which it refers.
Class diagram
Participants
● Mediator (DialogDirector)
○ defines an interface for communicating with Colleague objects.
● ConcreteMediator (FontDialogDirector)
○ implements cooperative behavior by coordinating Colleague objects.
○ knows and maintains its colleagues.
● Colleague classes (ListBox, EntryField)
○ each Colleague class knows its Mediator object.
○ each colleague communicates with its mediator whenever it would have
otherwise communicated with another colleague.
Example #3: employee chat
Friend1 and Friend2 are
employees at Boss’s team.
DESIGN PATTERN
There are 3 main participants in the memento pattern’s class
diagrams – Originator, Memento and Caretaker.
● Originator is the object of which the state is to be stored. The responsibilities of storing the
snapshot of its state and then restoring the state from Memento lie with Originator.
● Memento stores the internal state of the Originator. Only Originator is allowed storing
to/restoring from the Memento object. This allows the internal structure/state of Originator
to not be visible to other classes thus achieving the encapsulation requirement of a
Memento implementation.
● Caretaker holds the memento object and is responsible for its safekeeping. When a
snapshot of the Originator’s state is required then the Caretaker asks the Originator for the
snapshot as a memento object and stores the snapshot. When the Originator’s state is to be
restored then Caretaker passes the Memento object back to the Originator.
UML
//Originator
public class Project {
}
public class Client {
public static void main(String[] args) throws InterruptedException {
GitRepo gitRepo = new GitRepo();
Project project = new Project();
System.out.println("---- Creating new project: Version 1.0");
project.setVersion("1.0");
System.out.println(project);
System.out.println("---- Saving current version to Git...");
gitRepo.add(project.save());
System.out.println("---- Writing poor code and Updating project to version 1.1");
Thread.sleep(5000); // optional field
project.setVersion("1.1");
System.out.println(project);
System.out.println("---- Saving current version to Git...");
gitRepo.add(project.save());
System.out.println("---- Working with current version and somethings went wrong... ");
System.out.println("---- Rolling back to version 1.0");
project.load(gitRepo.get("1.0"));
System.out.println("--------------------------------");
System.out.println(project );
}}
//Output
DESIGN PATTERN
Definition
Define a one-to-many dependency between objects so that when one object changes
state, all its dependents are notified and updated automatically.
DESIGN PATTERN
The State pattern is known as a behavioural pattern - it's used to manage algorithms,
relationships and responsibilities between objects.
Thedefinition of State provided in the original Gang of Four book on Design Patterns states:
Allows an object to alter its behaviour when its internal state changes. The object will appear to change its
class.
UML
The Context can have a number of internal States, whenever the request() method is called on the
Context, the message is delegated to the State to handle. The State interface defines a common
interface for all concrete states, encapsulating all behaviour associated with a particular state. The
ConcreteState implements it's own implementation for the request. When a Context changes state,
what really happens is that we have a different ConcreteState associated with it.
State saves you from lots of conditional code in your Context: by changing the ConcreteState object
used, you can change the behaviour of the context.
DESIGN PATTERN
Strategy design pattern
Motivation
There are common situations when classes differ only in their behavior. For
this cases is a good idea to isolate the algorithms in separate classes in
order to have the ability to select different algorithms at runtime.
Intent
if(isValid) {
isValid = creditCard.getNumber().length() == 16;
}
if(isValid) {
isValid = passesLuhn(creditCard.getNumber());
}
return isValid;
}
}
public class AmexStrategy extends ValidationStrategy {
@Override
public boolean isValid(CreditCard creditCard) {
boolean isValid = true;
isValid = creditCard.getNumber().startsWith("37") ||
creditCard.getNumber().startsWith("34");
if(isValid) {
isValid = creditCard.getNumber().length() == 15;
}
if(isValid) {
isValid = passesLuhn(creditCard.getNumber());
}
return isValid;
}
}
public class StrategyDemo {
public static void main(String args[]) {
DESIGN PATTERN
UML
public abstract class HouseTemplate {
@Override @Override
public void buildWalls() { public void buildWalls() {
System.out.println("Building Wooden Walls"); System.out.println("Building Glass
} Walls");
}
@Override
public void buildPillars() { @Override
System.out.println("Building Pillars with public void buildPillars() {
Wood coating"); System.out.println("Building Pillars with
} glass coating");
}
}
}
public class HousingClient {
Output
public static void main(String[] args) {
HouseTemplate houseType = new Building foundation with cement,iron rods and sand
Building Pillars with Wood coating
WoodenHouse();
Building Wooden Walls
Building Glass Windows
//using template method
House is built.
houseType.buildHouse();
************
System.out.println("************");
Building foundation with cement,iron rods and sand
Building Pillars with glass coating
houseType = new GlassHouse();
Building Glass Walls
Building Glass Windows
houseType.buildHouse();
House is built.
}
}
Important points
1. Template method should consists of certain steps whose order is fixed and for some of the
methods, implementation differs from base class to subclass. Template method should be
final.
2. Most of the times, subclasses calls methods from super class but in template pattern,
superclass template method calls methods from subclasses, this is known as Hollywood
Principle – “don’t call us, we’ll call you.”.
3. Methods in base class with default implementation are referred as Hooks and they are
intended to be overridden by subclasses, if you want some of the methods to be not
overridden, you can make them final, for example in our case we can make buildFoundation()
method final because if we don’t want subclasses to override it.
DESIGN PATTERN
The Visitor Pattern
The Visitor is known as a behavioural pattern,as it's used to manage
algorithms, relationships and responsibilities between objects. Thedefinition of
Visitor provided in the original Gang of Four book on DesignPatterns states:
}
public class TestVisitor {
public static void main(String[] args) {
FirstTimeVisitor visitor = new FirstTimeVisitor();
City city = new City();
city.accept(visitor);
}
}
Output
City is accepting visitor.
I'm visiting the city!
Museum is accepting visitor.
I'm visiting the Museum!
Park is accepting visitor.
I'm visiting the Park!
public interface ProjectElement {
public void beWritten(Developer developer);
}
public class ProjectClass implements ProjectElement {
public void beWritten(Developer developer) {
developer.create(this);
}
}
public class Database implements ProjectElement{
public void beWritten(Developer developer) {
developer.create(this);
}
}
public class Test implements ProjectElement {
public void beWritten(Developer developer) {
developer.create(this);
}
}
public interface Developer { public class SeniorDeveloper implements Developer {
ProjectElement [] projectElements;
public Project() {
this.projectElements = new ProjectElement[]{
new ProjectClass(),
new Database(),
new Test()
};
}
System.out.println("Junior in action");
project.beWritten(junior);
System.out.println("\n#######################\n");
System.out.println("Junior in action");
project.beWritten(senior);
}
}
OutPut
Junior in action
Writing poor class...
Drop database...
Creating not reliable test...
#######################
Senior in action
Rewriting class after junior...
Fixing database...
Creating reliable test...
NULL OBJECT
DESIGN PATTERN
Intent
The intent of a Null Object is to encapsulate the absence of an object by providing a substitutable alternative that
offers suitable default do nothing behavior. In short, a design where "nothing will come of nothing".
● an object requires a collaborator. The Null Object pattern does not introduce this collaboration--it makes use
of a collaboration that already exists
● some collaborator instances should do nothing
● you want to abstract the handling of null away from the client
Problem
Given that an object reference may be optionally null, and that the result of a null check is to do nothing or use some
default value, how can the absence of an object — the presence of a null reference — be treated transparently?
UML
● Client -
○ requires a collaborator.
● AbstractObject -
○ defines a concrete subclass of AbstractObject whose instances provide useful behavior that Client expects
● NullObject -
○ provides an interface identical to AbstractObject's so that a null object can be substituted for a real object
○ implements its interface to do nothing. What exactly it means to do nothing depends on what sort of behavior
Client is expecting
○ when there is more than one way to do nothing, more than one NullObject class may be required
public abstract class AbstractCustomer {
protected String name;
public abstract boolean isNil();
public abstract String getName();
}
System.out.println("Customers");
System.out.println(customer1.getName());
System.out.println(customer2.getName());
System.out.println(customer3.getName());
System.out.println(customer4.getName());
}
}
THE END