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

Behavior Desgn Patterns

The Mediator pattern defines an object that acts as a communication hub between other objects, controlling interactions and promoting loose coupling by reducing dependencies between objects. An example implementation shows a mediator used to facilitate messaging between different concession stands at a movie theater, allowing them to communicate what supplies they need or have available. The mediator routes messages from one concession stand object to another, keeping them decoupled from each other.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
53 views26 pages

Behavior Desgn Patterns

The Mediator pattern defines an object that acts as a communication hub between other objects, controlling interactions and promoting loose coupling by reducing dependencies between objects. An example implementation shows a mediator used to facilitate messaging between different concession stands at a movie theater, allowing them to communicate what supplies they need or have available. The mediator routes messages from one concession stand object to another, keeping them decoupled from each other.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 26

Mediator Design Pattern

For our example, we will try to implement a chat application where users can do group chat. Every user will be
identified by it’s name and they can send and receive messages. The message sent by any user should be
received by all the other users in the group.

public interface ChatMediator { public class UserImpl extends User {


public void sendMessage(String msg, User user); public UserImpl(ChatMediator med, String name) {
void addUser(User user); super(med, name);
} }
public abstract class User { @Override
protected ChatMediator mediator; public void send(String msg){
protected String name; System.out.println(this.name+": Sending
public User(ChatMediator med, String name){ Message="+msg);
this.mediator=med; mediator.sendMessage(msg, this);
this.name=name; }
} @Override
public abstract void send(String msg); public void receive(String msg) {
public abstract void receive(String msg); System.out.println(this.name+": Received
} Message:"+msg);
import java.util.ArrayList; }
import java.util.List; }
public class ChatMediatorImpl implements ChatMediator public class ChatClient {
{ public static void main(String[] args) {
private List<User> users; ChatMediator mediator = new
public ChatMediatorImpl(){ ChatMediatorImpl();
this.users=new ArrayList<>(); User user1 = new UserImpl(mediator, "Pankaj");
} User user2 = new UserImpl(mediator, "Lisa");
public void addUser(User user){ User user3 = new UserImpl(mediator,
this.users.add(user); "Saurabh");
} User user4 = new UserImpl(mediator, "David");
public void sendMessage(String msg, User user) { mediator.addUser(user1);
for(User u : this.users){ mediator.addUser(user2);
if(u != user){ mediator.addUser(user3);
u.receive(msg); } mediator.addUser(user4);
} user1.send("Hi All");
}} }
}
Let’s consider the snack bars in your local movie theatre. Movie theatres, relative to other kinds of
buildings, tend to take up a lot of ground space. A particular cinema that's not too far from me has 25
screens spread out over three different "sections" of the theatre. Each of these sections, being far
enough apart from each other, has their own snack bar, from which we gluttonous patrons can order
salty snacks and sugary drinks to our increasingly-stressed heart's content. But selling concessions to
hungry movie-goers requires supplies, and sometimes the different snack bars might run out of said
supplies. Let's imagine a system in which the different concession stands can talk to each other,
communicating what supplies they need and who might have them (in short, a chat system for movie
snack bars). Let's model this using the Mediator pattern.

interface Mediator public void Notify(string message)


{ {
void SendMessage(string message, ConcessionStand Console.WriteLine("North Concession Stand gets
concessionStand); message: " + message);
} }
abstract class ConcessionStand }
{ class SouthConcessionStand : ConcessionStand
protected Mediator mediator; {
public ConcessionStand(Mediator mediator) public SouthConcessionStand(Mediator mediator) :
{ base(mediator)
this.mediator = mediator; {
} }
} public void Send(string message)
class NorthConcessionStand : ConcessionStand {
{ Console.WriteLine("South Concession Stand sends
// Constructor message: " + message);
public NorthConcessionStand(Mediator mediator) : mediator.SendMessage(message, this);
base(mediator) { } }
public void Send(string message)
{ public void Notify(string message)
Console.WriteLine("North Concession Stand sends {
message: " + message); Console.WriteLine("South Concession Stand gets
mediator.SendMessage(message, this); message: " + message);
} }
} }
class ConcessionsMediator : Mediator }
{ static void Main(string[] args)
private NorthConcessionStand _northConcessions; {
private SouthConcessionStand _southConcessions; ConcessionsMediator mediator = new
public NorthConcessionStand NorthConcessions ConcessionsMediator();
{
set { _northConcessions = value; } NorthConcessionStand leftKitchen = new
} NorthConcessionStand(mediator);
public SouthConcessionStand SouthConcessions SouthConcessionStand rightKitchen = new
{ SouthConcessionStand(mediator);
set { _southConcessions = value; } mediator.NorthConcessions = leftKitchen;
} mediator.SouthConcessions = rightKitchen;
public void SendMessage(string message, leftKitchen.Send("Can you send some popcorn?");
ConcessionStand colleague) rightKitchen.Send("Sure thing, Kenny's on his way.");
{ rightKitchen.Send("Do you have any extra hot dogs?
if (colleague == _northConcessions) We've had a rush on them over here.");
{ leftKitchen.Send("Just a couple, we'll send Kenny back
_southConcessions.Notify(message); with them.");
}
else Console.ReadKey();
{ }
_northConcessions.Notify(message);
}

Memento Design Pattern

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.

public class FileWriterUtil { this.fileName= memento.fileName;


private String fileName; this.content=memento.content;
private StringBuilder content; }
public FileWriterUtil(String file){ private class Memento{
this.fileName=file; private String fileName;
this.content=new StringBuilder(); private StringBuilder content;
} public Memento(String file,
@Override StringBuilder content){
public String toString(){ this.fileName=file;
return this.content.toString(); //notice the deep copy so that Memento and
} FileWriterUtil content variables don't refer to same
public void write(String str){ object
content.append(str); this.content=new
} StringBuilder(content);
public Memento save(){ }
return new }
Memento(this.fileName,this.content); }
} public class FileWriterCaretaker {
public void undoToLastSave(Object obj){ private Object obj;
Memento memento = (Memento) obj; public void save(FileWriterUtil fileWriter){
this.obj=fileWriter.save(); // lets save the file
} caretaker.save(fileWriter);
public void undo(FileWriterUtil fileWriter){ //now write something else
fileWriter.undoToLastSave(obj); fileWriter.write("Second Set of
} Data\n");
} //checking file contents
public class FileWriterClient { System.out.println(fileWriter+"\n\n");
public static void main(String[] args) { //lets undo to last save
FileWriterCaretaker caretaker = new caretaker.undo(fileWriter);
FileWriterCaretaker();
FileWriterUtil fileWriter = new //checking file content again
FileWriterUtil("data.txt"); System.out.println(fileWriter+"\n\n");
fileWriter.write("First Set of Data\n"); }
System.out.println(fileWriter+"\n\n"); }

Let's imagine a system in which a restaurant needs to record information about the suppliers that bring them
their ingredients. For example, a really high-end restaurant might order directly from a local farm, and the
restaurant needs to keep track of which ingredients come from which suppliers. In our system, we need to
keep track of how much information we enter about a particular supplier, and be able to restore that
information to a previous state if we, say, accidentally enter the wrong address. We can demo this using the
Memento pattern.
class FoodSupplier {
{ Console.WriteLine("\nSaving current state\n");
private string _name; return new FoodSupplierMemento(_name,
private string _phone; _phone, _address);
private string _address; }
public string Name public void RestoreMemento(FoodSupplierMemento
{ memento)
get { return _name; } {
set Console.WriteLine("\nRestoring previous state\n");
{ Name = memento.Name;
_name = value; Phone = memento.PhoneNumber;
Console.WriteLine("Proprietor: " + _name); Address = memento.Address;
} }
} }
public string Phone class FoodSupplierMemento
{ {
get { return _phone; } public string Name { get; set; }
set public string PhoneNumber { get; set; }
{ public string Address { get; set; }
_phone = value;
Console.WriteLine("Phone Number: " + _phone); public FoodSupplierMemento(string name, string
} phone, string address)
} {
public string Address Name = name;
{ PhoneNumber = phone;
get { return _address; } Address = address;
set }
{ }
_address = value; class SupplierMemory
Console.WriteLine("Address: " + _address); {
} private FoodSupplierMemento _memento;
}
public FoodSupplierMemento SaveMemento() public FoodSupplierMemento Memento
{ // Let's store that entry in our database.
set { _memento = value; } SupplierMemory m = new SupplierMemory();
get { return _memento; } m.Memento = s.SaveMemento();
} // Continue changing originator
} s.Address = "548 S Main St. Nowhere, KS";
static void Main(string[] args) // Crap, gotta undo that entry, I entered the wrong
{ address
//Here's a new supplier for our restaurant s.RestoreMemento(m.Memento);
FoodSupplier s = new FoodSupplier(); Console.ReadKey();
s.Name = "Harold Karstark"; }
s.Phone = "(482) 555-1172";

VISITOR
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. To implement
visitor pattern, first of all we will create different type of items (Elements) to be used in shopping cart.

public interface ItemElement { }


public int accept(ShoppingCartVisitor visitor); public class Fruit implements ItemElement {
} private int pricePerKg;
public class Book implements ItemElement { private int weight;
private int price; private String name;
private String isbnNumber; public Fruit(int priceKg, int wt, String nm){
public Book(int cost, String isbn){ this.pricePerKg=priceKg;
this.price=cost; this.weight=wt;
this.isbnNumber=isbn; this.name = nm;
} }
public int getPrice() { public int getPricePerKg() {
return price; return pricePerKg;
} }
public String getIsbnNumber() { public int getWeight() {
return isbnNumber; return weight;
} }
@Override public String getName(){
public int accept(ShoppingCartVisitor visitor) { return this.name;
return visitor.visit(this); }
} @Override
public int accept(ShoppingCartVisitor visitor) { public int visit(Fruit fruit) {
return visitor.visit(this); int cost = fruit.getPricePerKg()*fruit.getWeight();
} System.out.println(fruit.getName() + " cost = "+cost);
} return cost;
public interface ShoppingCartVisitor { }
}
int visit(Book book); public class ShoppingCartClient {
int visit(Fruit fruit); public static void main(String[] args) {
} ItemElement[] items = new ItemElement[]{new
public class ShoppingCartVisitorImpl implements Book(20, "1234"),new Book(100, "5678"),
ShoppingCartVisitor { new Fruit(10, 2, "Banana"), new Fruit(5, 5, "Apple")};
@Override int total = calculatePrice(items);
public int visit(Book book) { System.out.println("Total Cost = "+total);
int cost=0; }
//apply 5$ discount if book price is private static int calculatePrice(ItemElement[] items) {
greater than 50 ShoppingCartVisitor visitor = new
if(book.getPrice() > 50){ ShoppingCartVisitorImpl();
cost = book.getPrice()-5; int sum=0;
} for(ItemElement item : items){
else sum = sum + item.accept(visitor);
cost = book.getPrice(); }
System.out.println("Book return sum;
ISBN::"+book.getIsbnNumber() + " cost ="+cost); }
return cost; }
}

Let's create a seperate visitor for each postal region. This way, we can seperate the logic of calculating the total postage
cost from the items themselves. This means that our individual elements don't need to know anything about the postal
cost policy, and therefore, are nicely decoupled from that logic.

public interface Visitable{ public interface Visitor{


public void accept(Visitor visitor); public void visit(Book book);
}
Now, we'll create a concrete implementation of our //visit other concrete items
interface, a Book. public void visit(CD cd);
public void visit(DVD dvd);
//concrete element }
public class Book implements Visitable{ public class PostageVisitor implements Visitor {
private double price; private double totalPostageForCart;
private double weight; //collect data about the book
//accept the visitor public void visit(Book book) {
public void accept(Visitor vistor) { //assume we have a calculation here related to
visitor.visit(this); weight and price
} //free postage for a book over 10
public double getPrice() { if(book.getPrice() < 10.0) {
return price; totalPostageForCart += book.getWeight() * 2;
} }
public double getWeight() { }
return weight; //add other visitors here
} public void visit(CD cd) {...}
} public void visit(DVD dvd) {...}
//return the internal state PostageVisitor visitor = new PostageVisitor();
public double getTotalPostage() { //iterate through all items
return totalPostageForCart; for(Visitable item: items) {
} item.accept(visitor);
} }
public class ShoppingCart { double postage = visitor.getTotalPostage();
//normal shopping cart stuff return postage;
private ArrayList<Visitable> items; }
public double calculatePostage() { }
//create a visitor
Stratergy
Let's consider an application used to simulate and study robots interaction. For the beginning a simple application is
created to simulate an arena where robots are interacting. We have the following classes:

IBehaviour (Strategy) - an interface that defines the behavior of a robot

Conctete Strategies: AggressiveBehaviour, DefensiveBehaviour, NormalBehaviour; each of them defines a specific


behavior. In order to decide the action this class needs information that is passed from robot sensors like position, close
obstacles, etc.

Robot - The robot is the context class. It keeps or gets context information such as position, close obstacles, etc, and
passes necessary information to the Strategy class.

In the main section of the application the several robots are created and several different behaviors are created. Each
robot has a different behavior assigned: 'Big Robot' is an aggressive one and attacks any other robot found, 'George
v.2.1' is really scared and run away in the opposite direction when it encounter another robot and 'R2' is pretty calm and
ignore any other robot. At some point the behaviors are changed for each robot.

public interface IBehaviour { public class NormalBehaviour implements IBehaviour{


public int moveCommand(); public int moveCommand()
} {
public class AgressiveBehaviour implements IBehaviour{ System.out.println("\tNormal Behaviour: if find another
public int moveCommand() robot ignore it");
{ return 0;
System.out.println("\tAgressive Behaviour: if find }
another robot attack it"); }
return 1; public class Robot {
} IBehaviour behaviour;
} String name;

public class DefensiveBehaviour implements public Robot(String name)


IBehaviour{ {
public int moveCommand() this.name = name;
{ }
System.out.println("\tDefensive Behaviour: if find public void setBehaviour(IBehaviour behaviour)
another robot run from it"); {
return -1; this.behaviour = behaviour;
} }
} public IBehaviour getBehaviour()
{
return behaviour; Robot r1 = new Robot("Big Robot");
} Robot r2 = new Robot("George v.2.1");
public void move() Robot r3 = new Robot("R2");
{ r1.setBehaviour(new AgressiveBehaviour());
System.out.println(this.name + ": Based on current r2.setBehaviour(new DefensiveBehaviour());
position" + "the behaviour object decide the next r3.setBehaviour(new NormalBehaviour());
move:"); r1.move();
int command = behaviour.moveCommand(); r2.move();
// ... send the command to mechanisms r3.move();
System.out.println("\tThe result returned by behaviour System.out.println("\r\nNew behaviours: " +
object " +"is sent to the movement mechanisms " + " for "\r\n\t'Big Robot' gets really scared" + "\r\n\t, 'George
the robot '" + this.name + "'"); v.2.1' becomes really mad because" +"it's always
} attacked by other robots" +"\r\n\t and R2 keeps its
public String getName() { calm\r\n");
return name; r1.setBehaviour(new DefensiveBehaviour());
} r2.setBehaviour(new AgressiveBehaviour());
public void setName(String name) { r1.move();
this.name = name; r2.move();
} r3.move();
} }
public class Main { }
public static void main(String[] args) {

For our example, we will try to implement a simple Shopping Cart where we have two payment strategies –
using Credit Card or using PayPal. First of all we will create the interface for our strategy pattern example, in
our case to pay the amount passed as argument.

public interface PaymentStrategy { this.cardNumber=ccNum;


public void pay(int amount); this.cvv=cvv;
} this.dateOfExpiry=expiryDate;
public class CreditCardStrategy implements }
PaymentStrategy { @Override
private String name; public void pay(int amount) {
private String cardNumber; System.out.println(amount +" paid with
private String cvv; credit/debit card");
private String dateOfExpiry; }
public CreditCardStrategy(String nm, String }
ccNum, String cvv, String expiryDate){ public class PaypalStrategy implements
this.name=nm; PaymentStrategy {
private String emailId; public void addItem(Item item){
private String password; this.items.add(item);
public PaypalStrategy(String email, String pwd){ }
this.emailId=email; public void removeItem(Item item){
this.password=pwd; this.items.remove(item);
} }
@Override public int calculateTotal(){
public void pay(int amount) { int sum = 0;
System.out.println(amount + " paid for(Item item : items){
using Paypal."); sum += item.getPrice();
} }
} return sum;
public class Item { }
private String upcCode; public void pay(PaymentStrategy
private int price; paymentMethod){
public Item(String upc, int cost){ int amount = calculateTotal();
this.upcCode=upc; paymentMethod.pay(amount);
this.price=cost; }
} }
public String getUpcCode() { public class ShoppingCartTest {
return upcCode; public static void main(String[] args) {
} ShoppingCart cart = new
public int getPrice() { ShoppingCart();
return price; Item item1 = new Item("1234",10);
} Item item2 = new Item("5678",40);
} cart.addItem(item1);
cart.addItem(item2);
import java.text.DecimalFormat; //pay by paypal
import java.util.ArrayList; cart.pay(new
import java.util.List; PaypalStrategy("[email protected]", "mypwd"));
public class ShoppingCart { //pay by credit card
//List of items cart.pay(new
List<Item> items; CreditCardStrategy("Pankaj Kumar",
public ShoppingCart(){ "1234567890123456", "786", "12/15"));
this.items=new ArrayList<Item>(); }
} }
Interpreter Design Pattern
The classical example fot the interpreter pattern is the one of interpreting the roman numerals. The expresion to be
interpreted is a string which is put in the context. The context consists of the remaining unparsed Roman Numeral string
and of the result of the numerral that are already parsed. The context is passed to one of four sub-interpreters based on
the type of interpreting(Thousand, Hundred, Ten, One). This example it's using only TerminalExpressions.
The following participant classes are involved in this example: Context - keeps the current string that has to be parsed
and the decimal that contains the conversion already done. Initially the context keeps the full string that has to be
converted and 0 for the output decimal.

public class Context { }


else if (context.getInput().startsWith(four()))
private String input; {
private int output; context.setOutput(context.getOutput() + (4 *
multiplier()));
public Context(String input) context.setInput(context.getInput().substring(2));
{ }
this.input = input; else if (context.getInput().startsWith(five()))
} {
context.setOutput(context.getOutput() + (5 *
public String getInput() multiplier()));
{ context.setInput( context.getInput().substring(1));
return input; }
}
while (context.getInput().startsWith(one()))
public void setInput(String input) {
{ context.setOutput(context.getOutput() + (1 *
this.input = input; multiplier()));
} context.setInput(context.getInput().substring(1));
}
public int getOutput() }
{
return output; public abstract String one();
} public abstract String four();
public abstract String five();
public void setOutput(int output) public abstract String nine();
{ public abstract int multiplier();
this.output = output;
} }

} public class ThousandExpression extends Expression{

public abstract class Expression { public String one() { return "M"; }


public String four(){ return " "; }
public void interpret(Context context) public String five(){ return " "; }
{ public String nine(){ return " "; }
if (context.getInput().length() == 0) public int multiplier() { return 1000; }
return; }

if (context.getInput().startsWith(nine())) public class HundredExpression extends Expression{


{ public String one() { return "C"; }
context.setOutput(context.getOutput() + (9 * public String four(){ return "CD"; }
multiplier())); public String five(){ return "D"; }
context.setInput(context.getInput().substring(2)); public String nine(){ return "CM"; }
public int multiplier() { return 100; } public static void main(String[] args) {
}
String roman = "MCMXXVIII";
public class TenExpression extends Expression{ Context context = new Context(roman);
public String one() { return "X"; }
public String four(){ return "XL"; } // Build the 'parse tree'
public String five(){ return "L"; } ArrayList<Expression> tree = new
public String nine(){ return "XC"; } ArrayList<Expression>();
public int multiplier() { return 10; } tree.add(new ThousandExpression());
} tree.add(new HundredExpression());
tree.add(new TenExpression());
public class OneExpression extends Expression{ tree.add(new OneExpression());
public String one() { return "I"; }
public String four(){ return "IV"; } // Interpret
public String five(){ return "V"; } for (Iterator it = tree.iterator(); it.hasNext();)
public String nine(){ return "IX"; } {
public int multiplier() { return 1; } Expression exp = (Expression)it.next();
} exp.interpret(context);
}
public class MainInterpreter {
System.out.println(roman + " = " +
/** Integer.toString(context.getOutput()));
* @param args }
*/ }

Given any string expression and a token, filter out the information you want. The below is a simple
parser program. the myParser method can be used to parse any expression. The composite, visit and
iterator patterns have been used.
import java.util.*; result =
class Parser{ Arrays.asList(toBeMatched);
private String expression; }
private String token; public List getParseResult() {
private List result; return result;
private String interpreted; }
public void interpret() {
public Parser(String e, String t) { StringBuffer buffer = new StringBuffer();
expression = e; ListIterator list= result.listIterator();
token = t; while (list.hasNext()){
} String token = (String)list.next();
if (token.equals("SFO")){
public void myParser() { token = "San Francisco";
StringTokenizer holder=new }else if(token.equals("CA"))
StringTokenizer(expression, token); {
String[] toBeMatched = new token = "Canada";
String[holder.countTokens()]; }
int idx = 0; //...
while(holder.hasMoreTokens()) { buffer.append(" " + token);
String item = holder.nextToken(); }
int start = item.indexOf(","); interpreted = buffer.toString();
if(start==0) { }
item = item.substring(2); public String getInterpretedResult()
} {
toBeMatched[idx] = item; return interpreted;
idx ++; }
} public static void main(String[] args) {
String source = String result=
"dest='SFO',origin='CA',day='MON'"; parser.getInterpretedResult();
String delimiter = "=,'"; System.out.println(result);
Parser parser = new Parser(source, }
delimiter); }
parser.myParser(); java Parser
parser.interpret(); dest San Francisco origin Canada day MON

CHAIN OF RESPONSIBILITY

Here comes a simple example, just to show how chain of responsibility works. Whenever you
spend company's money, you need get approval from your boss, or your boss's boss. Let's say, the
leadership chain is:
Manager-->Director-->Vice President-->President

The following is a command line program to check who is responsible to approve your expenditure.
import java.io.*; if( successor != null)
abstract class PurchasePower {
successor.processRequest(request);
protected final double base = 500; }
protected PurchasePower successor; }

public void setSuccessor(PurchasePower class VicePresident extends PurchasePower


successor){ {
this.successor = successor; private final double ALLOWABLE = 40 *
} base;
abstract public void
processRequest(PurchaseRequest request); public void
} processRequest(PurchaseRequest request) {
if( request.getAmount() <
class Manager extends PurchasePower { ALLOWABLE )
private final double ALLOWABLE = 10 * System.out.println("Vice
base; President will approve $" +
request.getAmount());
public void else
processRequest(PurchaseRequest request ) if( successor != null )
{
if( request.getAmount() < ALLOWABLE ) successor.processRequest(request);
System.out.println("Manager will }
approve $"+ request.getAmount()); }
else
if( successor != null) class President extends PurchasePower {
private final double ALLOWABLE = 60 *
successor.processRequest(request); base;
}
} public void
processRequest(PurchaseRequest request){
class Director extends PurchasePower { if( request.getAmount() < ALLOWABLE )
private final double ALLOWABLE = 20 * System.out.println("President
base; will approve $" + request.getAmount());
else
public void System.out.println( "Your
processRequest(PurchaseRequest request ) request for $" + request.getAmount() + "
{ needs a board meeting!");
if( request.getAmount() < ALLOWABLE ) }
System.out.println("Director will }
approve $"+ request.getAmount());
else class PurchaseRequest {
}
private int number;
private double amount; class CheckAuthority {
private String purpose; public static void main(String[]
args) throws Exception{
public PurchaseRequest(int number, Manager manager = new Manager();
double amount, String purpose){ Director director = new
this.number = number; Director();
this.amount = amount; VicePresident vp = new
this.purpose = purpose; VicePresident();
} President president = new
President();
public double getAmount() { manager.setSuccessor(director);
return amount; director.setSuccessor(vp);
} vp.setSuccessor(president);
public void setAmount(double amt){
amount = amt; //enter ctrl+c to kill.
} while (true) {
System.out.println("Enter the
public String getPurpose() { amount to check who should approve your
return purpose; expenditure.");
} System.out.print(">");
public void setPurpose(String reason) double d =
{ Double.parseDouble(new BufferedReader(new
purpose = reason; InputStreamReader(System.in)).readLine())
} ;
manager.processRequest(new
public int getNumber(){ PurchaseRequest(0, d, "General"));
return number; }
}
public void setNumber(int num) { }
number = num; }
}
One of the great example of Chain of Responsibility pattern is ATM Dispense machine. The user enters the
amount to be dispensed and the machine dispense amount in terms of defined currency bills such as 50$, 20$,
10$ etc. If the user enters an amount that is not multiples of 10, it throws error. We will use Chain of
Responsibility pattern to implement this solution. The chain will process the request in the same order as below
image.
public class Currency { }
private int amount; public class Dollar10Dispenser implements
public Currency(int amt){ DispenseChain {
this.amount=amt; private DispenseChain chain;
} @Override
public void setNextChain(DispenseChain nextChain) {
public int getAmount(){ this.chain=nextChain;
return this.amount; }
} @Override
} public void dispense(Currency cur) {
public interface DispenseChain { if(cur.getAmount() >= 10){
void setNextChain(DispenseChain nextChain); int num = cur.getAmount()/10;
void dispense(Currency cur); int remainder = cur.getAmount() % 10;
} System.out.println("Dispensing "+num+" 10$ note");
public class Dollar50Dispenser implements if(remainder !=0) this.chain.dispense(new
DispenseChain { Currency(remainder));
private DispenseChain chain; }else{
@Override this.chain.dispense(cur);
public void setNextChain(DispenseChain }
nextChain) { }
this.chain=nextChain;
} }
@Override import java.util.Scanner;
public void dispense(Currency cur) { public class ATMDispenseChain {
if(cur.getAmount() >= 50){ private DispenseChain c1;
int num = cur.getAmount()/50; public ATMDispenseChain() {
int remainder = cur.getAmount() % 50; // initialize the chain
System.out.println("Dispensing "+num+" 50$ note"); this.c1 = new Dollar50Dispenser();
if(remainder !=0) this.chain.dispense(new DispenseChain c2 = new Dollar20Dispenser();
Currency(remainder)); DispenseChain c3 = new Dollar10Dispenser();
}else{
this.chain.dispense(cur); // set the chain of responsibility
} } c1.setNextChain(c2);
} c2.setNextChain(c3);
public class Dollar20Dispenser implements }
DispenseChain{ public static void main(String[] args) {
private DispenseChain chain; ATMDispenseChain atmDispenser = new
@Override ATMDispenseChain();
public void setNextChain(DispenseChain nextChain) { while (true) {
this.chain=nextChain; int amount = 0;
} System.out.println("Enter amount to dispense");
@Override Scanner input = new Scanner(System.in);
public void dispense(Currency cur) { amount = input.nextInt();
if(cur.getAmount() >= 20){ if (amount % 10 != 0) {
int num = cur.getAmount()/20; System.out.println("Amount should be in multiple of
int remainder = cur.getAmount() % 20; 10s.");
System.out.println("Dispensing "+num+" 20$ note"); return;
if(remainder !=0) this.chain.dispense(new }
Currency(remainder)); // process the request
}else{ atmDispenser.c1.dispense(new Currency(amount));
this.chain.dispense(cur); }
}
}
FlyWeight
For our example, lets say we need to create a drawing with lines and Ovals. So we will have an
interface Shapeand its concrete implementations as Line and Oval. Oval class will have intrinsic property to
determine whether to fill the Oval with given color or not whereas Line will not have any intrinsic property.
import java.awt.Color; }
import java.awt.Graphics; @Override
public interface Shape { public void draw(Graphics circle, int x, int y, int
public void draw(Graphics g, int x, int y, int width, int height,
width, int height, Color color) {
Color color); circle.setColor(color);
} circle.drawOval(x, y, width, height);
import java.awt.Color; if(fill){
import java.awt.Graphics; circle.fillOval(x, y, width,
height);
public class Line implements Shape { }
}
public Line(){
System.out.println("Creating Line }
object"); import java.util.HashMap;
//adding time delay public class ShapeFactory {
try { private static final HashMap<ShapeType,Shape>
Thread.sleep(2000); shapes = new HashMap<ShapeType,Shape>();
} catch (InterruptedException e) { public static Shape getShape(ShapeType type) {
e.printStackTrace(); Shape shapeImpl = shapes.get(type);
}
} if (shapeImpl == null) {
@Override if
public void draw(Graphics line, int x1, int y1, int (type.equals(ShapeType.OVAL_FILL)) {
x2, int y2, shapeImpl = new
Color color) { Oval(true);
line.setColor(color); } else if
line.drawLine(x1, y1, x2, y2); (type.equals(ShapeType.OVAL_NOFILL)) {
} shapeImpl = new
Oval(false);
} } else if
import java.awt.Color; (type.equals(ShapeType.LINE)) {
import java.awt.Graphics; shapeImpl = new Line();
public class Oval implements Shape { }
shapes.put(type, shapeImpl);
//intrinsic property }
private boolean fill; return shapeImpl;
}
public Oval(boolean f){
this.fill=f; public static enum ShapeType{
System.out.println("Creating Oval OVAL_FILL,OVAL_NOFILL,LINE;
object with fill="+f); }
//adding time delay }
try { import java.awt.BorderLayout;
Thread.sleep(2000); import java.awt.Color;
} catch (InterruptedException e) { import java.awt.Container;
e.printStackTrace(); import java.awt.Graphics;
} import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; Shape shape =
import javax.swing.JButton; ShapeFactory.getShape(getRandomShape());
import javax.swing.JFrame; shape.draw(g,
import javax.swing.JPanel; getRandomX(), getRandomY(), getRandomWidth(),
import
com.journaldev.design.flyweight.ShapeFactory.ShapeTy getRandomHeight(), getRandomColor());
pe; }
public class DrawingClient extends JFrame{ }
private static final long serialVersionUID = - });
1350200437285282550L; }
private final int WIDTH; private ShapeType getRandomShape() {
private final int HEIGHT; return shapes[(int) (Math.random() *
shapes.length)];
private static final ShapeType shapes[] = { }
ShapeType.LINE, private int getRandomX() {
ShapeType.OVAL_FILL,ShapeType.OVAL_NOFILL }; return (int) (Math.random() * WIDTH);
private static final Color colors[] = { Color.RED, }
Color.GREEN, Color.YELLOW }; private int getRandomY() {
return (int) (Math.random() * HEIGHT);
public DrawingClient(int width, int height){ }
this.WIDTH=width; private int getRandomWidth() {
this.HEIGHT=height; return (int) (Math.random() * (WIDTH /
Container contentPane = getContentPane(); 10));
JButton startButton = new JButton("Draw"); }
final JPanel panel = new JPanel(); private int getRandomHeight() {
contentPane.add(panel, BorderLayout.CENTER); return (int) (Math.random() * (HEIGHT /
contentPane.add(startButton, 10));
BorderLayout.SOUTH); }
setSize(WIDTH, HEIGHT); private Color getRandomColor() {
return colors[(int) (Math.random() *
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); colors.length)];
setVisible(true); }
startButton.addActionListener(new public static void main(String[] args) {
ActionListener() { DrawingClient drawing = new
public void DrawingClient(500,600);
actionPerformed(ActionEvent event) { }
Graphics g = }
panel.getGraphics();
for (int i = 0; i < 20; ++i)
{
In a war game example UnitFactory can create military units. In this example I have created two types of
units: Soldier and Tank. This classes are concrete flyweights which inherits from Unit flyweight base class.

UnitFactory class contains method called GetUnit which accept one parameter that specify type of unit to create.
This class has one private dictionary of unit types. When new unit is required, the first step is to look into this
dictionary whether this type of unit was created earlier. If yes, program returns reference to this unit. If no, it just
create a new unit and places it into dictionary. You can control the number of instances of each unit type by static
field NumberOfInstances.

public class Soldier:Unit }


{
public static int NumberOfInstances; public class UnitFactory
{
public Soldier() private readonly Dictionary&lt;string, Unit> _units =
{ new Dictionary&lt;string, Unit>();
NumberOfInstances++;
} public Unit GetUnit(string type)
{
public override void FireAt(Target target) if (_units.ContainsKey(type))
{ {
Console.WriteLine("Shooting at unit {0} with power return _units[type];
of {1}." }
, target.ID, FirePower); Unit unit;
}
} switch (type)
{
public class Tank:Unit case "Infantry":
{ unit = new Soldier
public static int NumberOfInstances; {
Name = "Standard Infantry",
public Tank() Armour = 5,
{ Speed = 4,
NumberOfInstances++; RotationRate = 180,
} FireRate = 5,
Range = 100,
public override void FireAt(Target target) FirePower = 5
{ };
Console.WriteLine("Firing at {0} with power of {1}.", break;
target.ID, FirePower);
} case "Marine":
} unit = new Soldier
{
public abstract class Unit Name = "Marine",
{ Armour = 25,
public string Name { get; internal set; } Speed = 4,
public int Armour { get; internal set; } RotationRate = 180,
public int Speed { get; internal set; } FireRate = 3,
public int RotationRate { get; internal set; } Range = 200,
public int FireRate { get; internal set; } FirePower = 10
public int Range { get; internal set; } };
public int FirePower { get; internal set; } break;
public abstract void FireAt(Target target);
case "Tank": Target tank1 = new Target();
unit = new Tank tank1.ID = Guid.NewGuid();
{ tank1.UnitData = factory.GetUnit("Tank");
Name = "Tank",
Armour = 1000, Target tank2 = new Target();
Speed = 25, tank2.ID = Guid.NewGuid();
RotationRate = 5, tank2.UnitData = factory.GetUnit("Tank");
FireRate = 30,
Range = 1000, bool result = tank1.UnitData == tank2.UnitData;
FirePower = 250 // result = true
}; int firepower = tank1.UnitData.FirePower;
break;
Console.WriteLine("Tank Instances: "+
default: Tank.NumberOfInstances);
throw new ArgumentException();
} Target soldier1 = new Target();
soldier1.ID = Guid.NewGuid();
_units.Add(type, unit); soldier1.UnitData = factory.GetUnit("Marine");
return unit;
} var soldier2 = new Target();
} soldier2.UnitData = factory.GetUnit("Infantry");
soldier2.ID = Guid.NewGuid();
public class Target
{ var soldier3 = new Target();
public Unit UnitData; soldier3.UnitData = factory.GetUnit("Infantry");
public Guid ID; soldier3.ID = Guid.NewGuid();
}
Console.WriteLine("Soldier Instances: " +
class Program Soldier.NumberOfInstances);
{ }
static void Main(string[] args) }
{
UnitFactory factory = new UnitFactory();
Bridge pattern
The example of TV and Remote Control(typo in diagram) can demonstrate the two layers of
abstraction. You have an interface for TV and an abstract class for remote control. As you
know, it is not a good idea to make a concrete class for either of them, because other vendors
may make different implementations.

public interface ITV {


public void on(); @Override
public void off(); public void off() {
public void switchChannel(int channel); System.out.println("Sony is turned
} off.");
public class SamsungTV implements ITV { }
@Override
public void on() { @Override
System.out.println("Samsung is turned public void switchChannel(int channel) {
on."); System.out.println("Sony: channel - " +
} channel);
}
@Override }
public void off() { public abstract class AbstractRemoteControl {
System.out.println("Samsung is turned /**
off."); * @uml.property name="tv"
} * @uml.associationEnd
*/
@Override private ITV tv;
public void switchChannel(int channel) {
System.out.println("Samsung: channel - public AbstractRemoteControl(ITV tv){
" + channel); this.tv = tv;
} }
}
public class SonyTV implements ITV { public void turnOn(){
tv.on();
@Override }
public void on() {
System.out.println("Sony is turned public void turnOff(){
on."); tv.off();
} }
}
public void setChannel(int channel){ }
tv.switchChannel(channel); public class Main {
} public static void main(String[] args){
} ITV tv = new SonyTV();
public class LogitechRemoteControl extends LogitechRemoteControl lrc = new
AbstractRemoteControl { LogitechRemoteControl(tv);
lrc.setChannelKeyboard(100);
public LogitechRemoteControl(ITV tv) { }
super(tv); }
} Output:

public void setChannelKeyboard(int channel){ Sony: channel - 100


setChannel(channel); Logitech use keyword to set channel.
System.out.println("Logitech use
keyword to set channel.");

Sdc

Create a Question interface that provides the navigation from one question to another or vice-versa.

// this is the Question interface. Step 2


public interface Question {
public void nextQuestion(); Create a JavaQuestions implementation class that will
public void previousQuestion(); implement Question interface.
public void newQuestion(String q);
public void deleteQuestion(String q); // this is the JavaQuestions class.
public void displayQuestion(); import java.util.ArrayList;
public void displayAllQuestions(); import java.util.List;
} public class JavaQuestions implements Question {
// End of the Question interface.
private List <String> questions = new public QuestionManager(String catalog) {
ArrayList<String>(); this.catalog=catalog;
private int current = 0; }
public JavaQuestions(){ public void next() {
questions.add("What is class? "); q.nextQuestion();
questions.add("What is interface? "); }
questions.add("What is abstraction? "); public void previous() {
questions.add("How multiple polymorphism is q.previousQuestion();
achieved in java? "); }
questions.add("How many types of exception public void newOne(String quest) {
handling are there in java? "); q.newQuestion(quest);
questions.add("Define the keyword final for variable, }
method, and class in java? "); public void delete(String quest) {
questions.add("What is abstract class? "); q.deleteQuestion(quest);
questions.add("What is multi-threading? "); }
} public void display() {
public void nextQuestion() { q.displayQuestion();
if( current <= questions.size()-1 ) }
current++; public void displayAll() {
System.out.print(current); System.out.println("Question Paper: " + catalog);
} q.displayAllQuestions();
}
public void previousQuestion() { }// End of the QuestionManager class.
if( current > 0 ) Step 4
current--;
} Create a QuestionFormat class that will extend the
QuestionManager class
public void newQuestion(String quest) {
questions.add(quest); // this is the QuestionFormat class.
} public class QuestionFormat extends QuestionManager
{
public void deleteQuestion(String quest) { public QuestionFormat(String catalog){
questions.remove(quest); super(catalog);
} }
public void displayAll() {
public void displayQuestion() { System.out.println("\n--------------------------------------
System.out.println( questions.get(current) ); -------------------");
} super.displayAll();
public void displayAllQuestions() { System.out.println("-----------------------------------------
for (String quest : questions) { ------------------");
System.out.println(quest); }
} }// End of the QuestionFormat class.
} Step 5
}// End of the JavaQuestions class.
Step 3 Create a BridgePatternDemo class.

Create a QuestionManager class that will use Question // this is the BridgePatternDemo class.
interface which will act as a bridge.. public class BridgePatternDemo {
public static void main(String[] args) {
// this is the QuestionManager class. QuestionFormat questions = new
public class QuestionManager { QuestionFormat("Java Programming Language");
protected Question q; questions.q = new JavaQuestions();
public String catalog; questions.delete("what is class?");
questions.display(); questions.displayAll();
questions.newOne("What is inheritance? "); }
}// End of the BridgePatternDemo class.
questions.newOne("How many types of inheritance
are there in java?");

Builder Design Pattern


In the following example, we can define a drink builder called StarbucksBuilder which will
build a Starbucks drink. StarbucksBuilder has several steps to build a Starbucks drink, such
as buildSize() and buildDrink(). And finally return the drink built.

// produce to be built starbucks = new Starbucks();


class Starbucks { System.out.println("a drink is created");
private String size; }
private String drink;
public abstract void buildSize();
public void setSize(String size) { public abstract void buildDrink();
this.size = size; }
}
// Concrete Builder to build tea
public void setDrink(String drink) { class TeaBuilder extends StarbucksBuilder {
this.drink = drink; public void buildSize() {
} starbucks.setSize("large");
} System.out.println("build large size");
}
//abstract builder
abstract class StarbucksBuilder { public void buildDrink() {
protected Starbucks starbucks; starbucks.setDrink("tea");
System.out.println("build tea");
public Starbucks getStarbucks() { }
return starbucks;
} }

public void createStarbucks() { // Concrete builder to build coffee


class CoffeeBuilder extends StarbucksBuilder { starbucksBuilder.buildSize();
public void buildSize() { }
starbucks.setSize("medium"); }
System.out.println("build medium
size"); //customer
} public class Customer {
public static void main(String[] args) {
public void buildDrink() { Waiter waiter = new Waiter();
starbucks.setDrink("coffee"); StarbucksBuilder coffeeBuilder = new
System.out.println("build coffee"); CoffeeBuilder();
}
} //Alternatively you can use tea builder
to build a tea
//director to encapsulate the builder //StarbucksBuilder teaBuilder = new
class Waiter { TeaBuilder();
private StarbucksBuilder starbucksBuilder;

public void waiter.setStarbucksBuilder(coffeeBuilder);


setStarbucksBuilder(StarbucksBuilder builder) { waiter.constructStarbucks();
starbucksBuilder = builder;
} //get the drink built
Starbucks drink =
public Starbucks getstarbucksDrink() { waiter.getstarbucksDrink();
return starbucksBuilder.getStarbucks();
} }
}
public void constructStarbucks() {
starbucksBuilder.createStarbucks();
starbucksBuilder.buildDrink();

Let´s implement a cake bakery. A colleague of yours wants to open a bakery and asked you to program a
bakery’s software for him. Ingredient is the Part, Recipe is the BuilderContract and Builder is the builder
itself. Cake is the final, customizable product. CakeBuilder is the class which actually creates the product
after customization (after the addition of as many parts – ingredients – as you want). The client would be
the final client or your colleague taking the order.
// 1. EXAMPLE: PART TO CUSTOMIZATE "INGREDIENTS" this.unitPrice = unitPrice;
public interface Ingredient { }
3 // INGREDIENTS WILL HAVE... @Override
4 void printName(); public void printName() {System.out.printf(" Light
String getUnitPrice(); Milk");}
void printCalories(); @Override public String getUnitPrice() {return
} unitPrice;}
public class LightMilk implements Ingredient { @Override public void printCalories()
private int deciLiter; {System.out.printf(" 76kc");}
private int calories; public int getDeciLiter() {return deciLiter;}
private String unitPrice; public void setDeciLiter(int deciLiter) {this.deciLiter =
public LightMilk(int deciLiter){this.deciLiter=deciLiter;} deciLiter;}
public LightMilk(int deciLiter, int calories, String public int getCalories() {return calories;}
unitPrice) { public void setCalories(int calories) {this.calories =
super(); calories;}
this.deciLiter = deciLiter; public void setUnitPrice(String unitPrice)
this.calories = calories; {this.unitPrice = unitPrice;}
} private String unitPrice;
public class Sugar implements Ingredient { public NoSugar(int deciLiter){this.gram=deciLiter;}
private int gram; public NoSugar(int gram, int calories, String unitPrice)
private int calories; {
private String unitPrice; super();
public Sugar(int deciLiter){this.gram=deciLiter;} this.gram = gram;
public Sugar(int gram, int calories, String unitPrice) { this.calories = calories;
super(); this.unitPrice = unitPrice;
this.gram = gram; }
this.calories = calories; @Override public void printName()
this.unitPrice = unitPrice; {System.out.printf(" No Sugar");}
} @Override public String getUnitPrice() {return
@Override public void printName() unitPrice;}
{System.out.printf(" Sugar");} @Override public void printCalories()
@Override public String getUnitPrice() {return {System.out.printf(" 0kc");}
unitPrice;} public int getGram() {return gram;}
@Override public void printCalories() public void setGram(int gram) {this.gram = gram;}
{System.out.printf(" 40kc");} public int getCalories() {return calories;}
public int getGram() {return gram;} public void setCalories(int calories) {this.calories =
public void setGram(int gram) {this.gram = gram;} calories;}
public int getCalories() {return calories;} public void setUnitPrice(String unitPrice)
public void setCalories(int calories) {this.calories = {this.unitPrice = unitPrice;}
calories;} }
public void setUnitPrice(String unitPrice) public class Milk implements Ingredient {
{this.unitPrice = unitPrice;} private int deciLiter;
} private int calories;
public class Choco implements Ingredient { private String unitPrice;
private int gram; public Milk(int deciLiter){this.deciLiter=deciLiter;}
private int calories; public Milk(int deciLiter, int calories, String unitPrice)
private String unitPrice; {
public Choco(int gram, int calories, String unitPrice) { super();
super(); this.deciLiter = deciLiter;
this.gram = gram; this.calories = calories;
this.calories = calories; this.unitPrice = unitPrice;
this.unitPrice = unitPrice; }
} @Override public void printName()
public int getGram() {return gram;} {System.out.printf(" Milk");}
public void setGram(int gram) {this.gram = gram;} @Override public String getUnitPrice() {return
public int getCalories() {return calories;} unitPrice;}
public void setCalories(int calories) {this.calories = @Override public void printCalories()
calories;} {System.out.printf(" 128kc");}
public void setUnitPrice(String unitPrice) public int getDeciLiter() {return deciLiter;}
{this.unitPrice = unitPrice;} public void setDeciLiter(int deciLiter) {this.deciLiter =
@Override public void printName() deciLiter;}
{System.out.printf(" Chocolate");} public int getCalories() {return calories;}
@Override public void printCalories() public void setCalories(int calories) {this.calories =
{System.out.printf(" 389kc");} calories;}
@Override public String getUnitPrice() {return public void setUnitPrice(String unitPrice)
unitPrice;} {this.unitPrice = unitPrice;}
} }
public class NoSugar implements Ingredient { The Builder’s Contract
private int gram; This is the Recipe in our example.
private int calories; // 2. THE BUILDER METHOD WILL ADD
// INGREDIENTS RETURNING THE BUILDER ITSELF // PRINT OUT PART PRICES
public interface Recipe < B > { for (Ingredient ingredient : ingredients) {
B addIngredient(Ingredient ingredient); muffin+=" "+ingredient.getUnitPrice();//NOPMD
} }
// 3. DEFINE THE BUILDER CONTRUCTION METHOD System.out.println(" - Price: "+muffin);
// WHICH BUILDS AND RETURNS THE FINAL PRODUCT }
"T" public void printResult(){
public interface Builder < T > extends Recipe < Builder < System.out.println(" Cake is ready!");
T>>{ }
T build(); }
} Testing it
import java.util.ArrayList; public class Client {
import java.util.List; public static void main(String[] args) {
// 4. IMPLEMENT THE BUILDER ACC. TO YOUR NEEDS Builder < Cake > chocoMuffinBuilder = new
public class CakeBuilder implements Builder < Cake > { CakeBuilder();
// IN THIS CASE THE PARTS ARE THE INGREDIENTS 05
private List < Ingredient > ingredients=new ArrayList < chocoMuffinBuilder.addIngredient(new Choco(10,
Ingredient > ( ); 23, "3.39"));
@Override chocoMuffinBuilder.addIngredient(new Milk(34,
public Cake build() { 67, "1.57"));
if(!ingredients.isEmpty()){ chocoMuffinBuilder.addIngredient(new Sugar(34,
// THE FINAL PRODUCT IS A CHOCO-MUFFIN 67, "2.00"));
return new Cake(ingredients); final Cake chocoMuffin =
} chocoMuffinBuilder.build();
return new Cake(null); chocoMuffin.printResult();
}
@Override }
// BECAUSE I ALWAYS GET A BUILDER BACK, I'M ABLE
TO }
// ADD A LOT OF PARTS BEFORE I CALL "BUILD()"
public Builder < Cake > addIngredient(Ingredient
ingredient) {
if(ingredient!=null){
ingredients.add(ingredient);
}
return this;
}
}
The product
In our example the product to build is a cake.
import java.util.List;
public class Cake {
public Cake(List < Ingredient > ingredients){
String muffin = "";
if(ingredients==null){
System.out.println(" zero cake "+muffin);
return;
}
// PRINT OUT MUFFIN INGREDIENTS
System.out.printf(" Cake with: ");
for (Ingredient ingredient : ingredients) {
ingredient.printName();
}

You might also like