Strategy Pattern
Example Problem Scenario
Suppose, you need to traverse the files and folders inside a given directory. So, you’ve decided to apply the BFS
algorithm. Following is a sample pseudo-code solution to the problem:
1 public class Traversal {2
3 public static void main(String[] args) {4
Node sourceNode; //Input the source node
5
6
Queue queue;
7
queue.push(sourceNode);8
while (!queue.isEmpty()) {9Node currentNode = queue.head(); //pops the head node and deletes it from queue10
Node[] children = currentNode.getChildrenNodes();11
for (Node node : children) {12
print(node); //print the node in whatever manner we like13
queue.push(node);
14
}
15
}
16 }
17 }

However, some time later, suppose you decided to use DFS instead of BFS. So, you’ll have to modify the code as
follows:
1 public class Traversal {2
3 public static void main(String[] args) {4
Node sourceNode; //Input the source node5
traverse(sourceNode);
6 }7
8 private static void traverse(Node currentNode) {9Node[] children = currentNode.getChildrenNodes();10for (Node node : children) {11
print(node); //print the node in whatever manner we like12
traverse(node);
13
}
14 }
15 }

Huge amount of change. This design has the following effects:
1. The class Traversal needs to be modified for the change in algorithm. But the class doesn’t need to know
anything about how the nodes are traversed.
2. The OCP (Open-Closed Principle1) of Object-Oriented Design Principles is violated.
How about the following solution?
1 interface TraversalAlgorithm {2 public void traverse(Node sourceNode);3}4
5 class BFS implements TraversalAlgorithm {6 public void traverse(Node SourceNode) {7
Queue queue;
8
queue.push(sourceNode);9
while (!queue.isEmpty()) {10
Node currentNode = queue.head(); //pops the head node and deletes it from queue
11
Node[] children = currentNode.getChildrenNodes();12for (Node node : children) {13
print(node); //print the node in whatever manner we like1

The OCP principle states that a class should be open for extension, but closed for modification.
1

14
queue.push(node);
Traversal
15
}
16
}
17 }
18 }
19
20 class DFS implements TraversalAlgorithm {21 public void traverse(Node SourceNode) {22
Node[] children = sourceNode.getChildrenNodes();23
for (Node node : children) {24
print(node); //print the node in whatever manner we like25
traverse(node);
26
}
27 }
Context
28 }29
30 public class Traversal {31 public static void main(String[] args) {32
Node sourceNode; //Input the source node
33
TraversalAlgorithm algorithm = new BFS();34
algorithm.traverse(sourceNode);
35//For DFS, just change BFS() to DFS()...
36 }
37 }

<<interface>>
TraversalAlgorithm+ traverse(sourceNode: Node): void

BFS

DFS

<<interface>>
Strategy+ algorithm()ConcreteStrategyAConcreteStrategyB

Figure: Strategy Pattern

Definition of Strategy Pattern
The strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable.
Strategy lets the algorithm vary independently from clients that use it.
Example Use Cases:
1. Implementing different sort algorithms (quick sort, merge sort etc.).
2. You have to encrypt a file.
For small files, you can use "in-memory" strategy, where the complete file is read and kept in memory (let’s
say for files less than 1 GB).
For large files, you can use another strategy, where parts of the file are read in memory and partial encrypted
results are stored in temporary files.
These are two different strategies for the same task. The client code would look the same.
3. Bob needs to get to work in a morning. Now it's up to him how he goes about getting there. From the point ofview of an outsider - Bob’s boss for instance, it doesn’t really matter how he gets to work, just that he arriveson time.
When Bob starts his day he can choose the method by which he gets to work, based on what is available. He
can assess if he has a car, if it is in a serviceable state and if the roads are clear. If not, Bob may decide to takethe train and take into account his proximity from the station and the availability of a given train. But nomatter what Bob's selected strategy may be, he is simply performing the action of getting to work.

2

Bridge Pattern
Example Problem Scenario
Suppose, you need to print some drawing shapes through a printer. Now, there can be various printers – laser, inkjet
etc – whose printing algorithm differs. We can accommodate this using the strategy pattern. However, a shape itself
has various forms – circle, square etc. So, for m shapes and n printers, there are m × n combinations. Is there any wayof implementing this easily?
Solution Step 1
The various shapes and the various printers can be implemented separately using the strategy pattern. Below are thenecessary classes:
1 interface Printer {2 public void print(byte[] data);
3}
4
5 class LaserPrinter implements Printer {6 public void print(byte[] data) {7//print data
8 }
9}
10
11 class InkjetPrinter implements Printer {12 public void print(byte[] data) {13//print data
14 }
15 }
16
17 abstract class Shape {19 protected byte[] data;24
25 abstract void prepareShapeData();
26 }27
28 class Circle extends Shape {29 void prepareShapeData() {30//Populate data with circle's pixels
31 }
32 }
33
34 class Square extends Shape {35 void prepareShapeData() {36//Populate data with square's pixels
37 }
38 }

Shape

<<interface>>
Printer~ data: byte[]
prepareShapeData(): void

CircleSquare+ print(data: byte[]): void

LaserPrint

InkjetPrinte

Solution Step 2 – Set up a bridge
17 abstract class Shape {18 public Printer printer;
19 protected byte[] data;
20
21 public void outputToPrinter() {22
printer.print(data);
23 }24
25 abstract void prepareShapeData();
26 }40 public class Client {41 public static void main(String[] args) {42
Shape shape = new Circle();43
shape.prepareShapeData();44
shape.printer = new LaserPrinter();45
shape.outputToPrinter();
46 }
47 }

Shape

<<interface>>
Printer+ printer: Printer~ data: byte[]+ print(data: byte[]): void
+ outputToPrinter(): void
prepareShapeData(): void
printer.print(data)
LaserPrinterCircleSquare3

InkjetPrinterDefinition of Bridge Pattern
The bridge pattern decouples an abstraction from its implementation so that the two can vary independently.

Figure: Bridge Pattern.

Example Use Cases
1. Switches are used to turn devices on and off. Devices can be of several types – light, fan etc. Again, switches
can be of several types, too – normal switch, push-button switch, touch switch etc. Now, bridge pattern can beused to map any switch to any device.

Adapter / Wrapper Pattern
Example Problem Scenario
Suppose, you have the following code that executes database queries. It uses (ficticious) MySQL class APIs.
1 public class Client {2 public static void main(String[] args) {3
MySQL mysql = new MySQL("localhost", "root", "", "someDB");4
mysql.connect();
5
List result = mysql.query("select * from someTable");6 }7}
8
9 class MySQL {10 private String host, user, pass, database;
11
12 MySQL(String host, String user, String pass, String database) {13
this.host = host;
14
this.user = user;
15
this.pass = pass;16
this.database = database;
17 }18
19 public void connect() {20//establish database connection with MySQL server
MySQL
21 }
22
- host : String- user : String
23 public List query(String query) {- pass : String
24
List result = new ArrayList<Object[]>();- database : String
25//fetch results from database and populate result list
+ MySQL(host: String, user: String, pass: String, database: String)26
return result;+ connect() : void
27 }+ query(query: String) : List
28 }Now, suppose you want to use Oracle class to use the Oracle database. The Oracle class is as follows:430 class Oracle {31 private String host, user, pass, database;32
33 Oracle(String host, String user, String pass, String database) {34
this.host = host;35
this.user = user;
36
this.pass = pass;37
this.database = database;38 }39
40 public void connectToServer() {41//establish database connection with MySQL server
42 }43
44 public List executeQuery(String query) {45
List result = new ArrayList<Object[]>();
46//fetch results from database and populate result list
47
return result;
48 }
49 }

Oracle- host : String- user : String- pass : String- database : String+ Oracle(host: String, user: String, pass: String, database: String)+ connectToServer() : void
+ executeQuery(query: String) : List

Both the MySQL and Oracle classes do the same thing. However, their method names are different – the constructors,
connect() vs. connectToServer() and query() vs. executeQuery(). Now, it’s not possible to change the vendor Oracle
class. We don’t want to take the pain to change the method calls in Client code, either. In this case, we can simply
provide a wrapper/adapter class which the Client code can use.
54 class MySQLToOracleAdapter {55 private Oracle oracle;
56
57 MySQLToOracleAdapter(String host, String user, String pass, String database) {58
oracle = new Oracle(host, user, pass, database);
59 }MySQLToOracleAdapter
60
61 public void connect() {- oracle : Oracle
62
oracle.connectToServer();+ MySQLToOracleAdapter(host: String, user: String, pass: String, database: String)63 }+ connectToServer() : void64
+ executeQuery(query: String) : List
65 public List query(String query) {66
return oracle.executeQuery(query);Oracle67 }68 }The only change the Client needs now is just renaming MySQL to MySQLToOracleAdapter in the object instantiation
statement.

Definition of Adapter Pattern
The adapter pattern converts the interface of a class into another interface the clients expect. Adapter lets classes
work together that couldn’t otherwise because of incompatible interfaces.
Types of Adapter
Object Adapter
This is the one we have been discussing.
Client<<interface>>
Targetrequest()Adapter

Adapteerequest()specificRequest()

5

Class Adapter
In class adapter, the Adapter subclasses Target and Adaptee (whereas in object adapter, composition is used to passrequests to an Adaptee). Class adapter uses multiple inheritance.
TargetClientAdapteerequest()specificRequest()

Adapterrequest()Observer Pattern
Example Problem Scenario
Suppose you’re writing an antivirus software. The antivirus has three components – real-time file protection, real-time
internet monitoring, always-on firewall. Now, suppose the user can give a command to pause and resume theantivirus. Upon pausing the antivirus, all the components would halt; and upon resume, all the components would
resume their monitoring tasks. Now the problem is, how would all those components get the notification of
pause/resume?
A quick solution can be as follows which includes only the pause action for brevity:
1 class RealTimeFileProtection {2 public void notifyPause() {3//pause current task
4 }5}
6
7 class RealTimeInternetMonitor {8 public void notifyPause() {9//pause current task
10 }
11 }
12
13 class AntivirusState {14 RealTimeFileProtection fileProtection;
15 RealTimeInternetMonitor internetMonitor;
16
17 public void pause() {18
fileProtection.notifyPause();19
internetMonitor.notifyPause();
20 }
21 }
22
23 public class Main {24 public static void main(String[] args) {25
RealTimeFileProtection fileProtection = new RealTimeFileProtection();26
RealTimeInternetMonitor internetMonitor = new RealTimeInternetMonitor();27
28
AntivirusState antivirusState = new AntivirusState();29
antivirusState.fileProtection = fileProtection;
30
antivirusState.internetMonitor = internetMonitor;
31
32
antivirusState.pause();
33 }
34 }

6

This solution works great! However, there is one problem – if we add another component, e.g. always-on firewall
which also needs to be notified of pause; then the AntivirusState class needs to be modified. This is a clear violation of
OCP (Open-Closed Principle). So, what can be done so that we can create as many components as we wish and can
notify them of pause without changing the code of AntivirusState? Let’s take a look at the following solution:
1 interface Observer {2 public void notifyPause();3}
4
5 class RealTimeFileProtection implements Observer {6 public void notifyPause() {7//pause current task
8 }
9}
10
11 class RealTimeInternetMonitor implements Observer {12 public void notifyPause() {13//pause current task
14 }
15 }
16
17 class AntivirusState {18 List<Observer> observers = new ArrayList<Observer>();19
20 public void registerForNotification(Observer observer) {21
observers.add(observer);22 }23
24 public void pause() {25
fileProtection.notifyPause();26
internetMonitor.notifyPause();
27 }
28 }
29
30 public class Main {31 public static void main(String[] args) {32
Observer fileProtection = new RealTimeFileProtection();
33
Observer internetMonitor = new RealTimeInternetMonitor();
34
35
AntivirusState antivirusState = new AntivirusState();36
antivirusState.registerForNotification(fileProtection);37
antivirusState.registerForNotification(internetMonitor);
38
39
antivirusState.pause();
40 }
41 }

To add, for example, Firewall class to the system and register it with the AntivirusState, we need to write the Firewallclass and change the Main class as follows:
1 class Firewall implements Observer {2 public void notifyPause() {3//pause current task
4 }5}
6
7 public class Main {8 public static void main(String[] args) {9
Observer fileProtection = new RealTimeFileProtection();
10
Observer internetMonitor = new RealTimeInternetMonitor();11
Observer firewall = new Firewall();
1213
AntivirusState antivirusState = new AntivirusState();14
antivirusState.registerForNotification(fileProtection);
15
antivirusState.registerForNotification(internetMonitor);
16
antivirusState.registerForNotification(firewall);
7

17
18
antivirusState.pause();
19 }
20 }

We can further reduce modifications by passing the AntivirusState object to the constructor of the components while
instantiating them:
1 class Firewall implements Observer {2 public Firewall(AntivirusState antivirusState) {3
antivirusState.registerForNotification(this);
4 }5
6 public void notifyPause() {7//pause current task
8 }
9}
10
11 public class Main {12 public static void main(String[] args) {13
AntivirusState antivirusState = new AntivirusState();14
15
Observer fileProtection = new RealTimeFileProtection(antivirusState);
16
Observer internetMonitor = new RealTimeInternetMonitor(antivirusState);
17
Observer firewall = new Firewall(antivirusState);
18
19
antivirusState.pause();
20 }
21 }

However, this solution tightly-couples the AntivirusState with the components. To loosen this coupling, we can passan interface to the components:
1 interface Subject {2 public void registerForNotification(Observer observer);3}
4
5 class AntivirusState implements Subject {6 List<Observer> observers = new ArrayList<Observer>();7
8 public void registerForNotification(Observer observer) {9observers.add(observer);10 }11
12 public void pause() {13
fileProtection.notifyPause();14
internetMonitor.notifyPause();
15 }
16 }
17
18 class Firewall implements Observer {19 public Firewall(Subject subject) {20
subject.registerForNotification(this);
21 }22
23 public void notifyPause() {24//pause current task
25 }
26 }
27
28 public class Observer_5 {29 public static void main(String[] args) {30
AntivirusState antivirusState = new AntivirusState();31
32
Observer fileProtection = new RealTimeFileProtection(antivirusState);
33
Observer internetMonitor = new RealTimeInternetMonitor(antivirusState);8

34
Observer firewall = new Firewall(antivirusState);
35
36
antivirusState.pause();
37 }
38 }

Figure: Observer Pattern (from Wikipedia)

Figure: Observer Pattern (from Head First Design Patterns)

Definition of Observer Pattern
The observer pattern defines a one-to-many
many dependency between objects so that when one object changes state, allof its dependents are notified and updated automatically.
Uses of Observer Pattern
Distributed event notification system.

9

State Pattern
Example Problem Scenario
Suppose, you have to write a program for a beverage vending machine. The working process of the machine can bedepicted by the following state diagram:ejectCoin(),selectBeverage(),
dispense()
insertCoin()
No CoininsertCoin(),ejectCoin(),selectBeverage()

insertCoin(),dispense()

selectBeverage()
Has Coin

BeverageSolddispense()ejectCoin()dispense()

The program can be easily written as follows:
1 public class BeverageVendingMachine {2 final static int NO_COIN = 0;
3 final static int HAS_COIN = 0;
4 final static int BEVERAGE_SOLD = 0;
5 final static int OUT_OF_BEVERAGE = 0;
6
7 private int currentState = NO_COIN;
8 private int numberOfAvailableBeverages;
9
10 BeverageVendingMachine(int initialNumberOfBeverages) {11
numberOfAvailableBeverages = initialNumberOfBeverages;12
if (numberOfAvailableBeverages == 0) {13
currentState = OUT_OF_BEVERAGE;
14
}
15 }
16
17 public void insertCoin() {18
if (currentState == NO_COIN) {19
currentState = HAS_COIN;
20
System.out.println("You've inserted coin.");21} else if (currentState == HAS_COIN) {22
System.out.println("You've already inserted a coin.");23} else if (currentState == BEVERAGE_SOLD) {24
System.out.println("Please wait, we're giving you a beverage.");25} else if (currentState == OUT_OF_BEVERAGE) {26
System.out.println("You can't insert a coin. All the beverages are sold out.");
27
}
28 }
29
30 public void ejectCoin() {31
if (currentState == NO_COIN) {32
System.out.println("You haven't inserted any coin.");33} else if (currentState == HAS_COIN) {34
currentState = NO_COIN;
35
System.out.println("Coin returned.");36} else if (currentState == BEVERAGE_SOLD) {37
System.out.println("Sorry, you've already selected a beverage.");38} else if (currentState == OUT_OF_BEVERAGE) {39
System.out.println("You can't eject, you haven't inserted a coin yet.");
40
}
41 }
42
43 public void selectBeverage() {44
if (currentState == NO_COIN) {45
System.out.println("You haven't inserted any coin.");46} else if (currentState == HAS_COIN) {10

insertCoin(),ejectCoin(),selectBeverage(),
dispense()
Out ofBeverage

47
currentState = BEVERAGE_SOLD;
48
System.out.println("You've selected a beverage.");49
dispense();50} else if (currentState == BEVERAGE_SOLD) {51
System.out.println("Selecting twice doesn't get you another beverage!");52} else if (currentState == OUT_OF_BEVERAGE) {53
System.out.println("Please insert a coin first.");
54
}
55 }
56
57 public void dispense() {58
if (currentState == NO_COIN) {59
System.out.println("You need to pay first.");60} else if (currentState == HAS_COIN) {61
System.out.println("Please select a beverage first.");62} else if (currentState == BEVERAGE_SOLD) {63
System.out.println("Beverage comes rolling out the slot!");64
numberOfAvailableBeverages--;65
if (numberOfAvailableBeverages == 0) {66
currentState = OUT_OF_BEVERAGE;
67} else {68
currentState = NO_COIN;
69}
70} else if (currentState == OUT_OF_BEVERAGE) {71
System.out.println("No beverage dispensed.");
72
}
73 }
74 }

Now, suppose you’d like to add a lottery system to the machine. After the customer gets his beverage, a lottery would
take place and the customer might win a free beverage. So, you’d have to add a new state WINNER to the system.
After the dispense of the beverage, if the customer wins the lottery, the system would make transition towards the
WINNER state; otherwise, the normal state transition would take place.
The problem is, adding a new state means adding a new if statement to all the methods. Is there any easier way to doit?
What we’ve done in the program
above is handling all the states foreach action. Let’s think reversely –we’ll handle all the actions for eachstate. The program is as follows:
1 interface State {2 public void insertCoin();3 public void ejectCoin();4 public void selectBeverage();5 public void dispense();6}

8 class HasCoinState implements State {9 BeverageVendingMachine machine;
10
11 public HasCoinState(BeverageVendingMachine machine) {12
this.machine = machine;
13 }14
15 public void insertCoin() {16System.out.println("You've already inserted a coin.");17 }18
19 public void ejectCoin() {20
System.out.println("Coin returned.");21
machine.setState(machine.getNoCoinState());
22 }
11

23
24 public void selectBeverage() {25
System.out.println("You've selected a beverage.");26
machine.setState(machine.getBeverageSoldState());
27 }28
29 public void dispense() {30
System.out.println("Please select a beverage first.");
31 }
32 }

34 class BeverageSoldState implements State {35 BeverageVendingMachine machine;
36
37 public BeverageSoldState(BeverageVendingMachine machine) {38
this.machine = machine;
39 }40
41 public void insertCoin() {42System.out.println("Please wait, we're giving you a beverage.");43 }44
45 public void ejectCoin() {46
System.out.println("Sorry, you've already selected a beverage.");47 }48
49 public void selectBeverage() {50
System.out.println("Selecting twice doesn't get you another beverage!");51 }52
53 public void dispense() {54machine.releaseBeverage();
55 }
56 }

58 class BeverageVendingMachine {59 State noCoinState;
60 State hasCoinState;
61 State beverageSoldState;
62 State outOfBeverageState;
63 private State currentState = noCoinState;
64 private int numberOfAvailableBeverages;
65
66 public BeverageVendingMachine(int initialNumberOfBeverages) {67
noCoinState = new NoCoinState(this);68
hasCoinState = new HasCoinState(this);69
beverageSoldState = new BeverageSoldState(this);70
outOfBeverageState = new OutOfBeverageState(this);71
72
numberOfAvailableBeverages = initialNumberOfBeverages;73
if (numberOfAvailableBeverages == 0) {74
currentState = outOfBeverageState;
75
}
76 }
77
78 public void setState(State state) {79
currentState = state;
80 }81
82 public State getNoCoinState() {83
return noCoinState;
84 }85
86 public State getHasCoinState() {12

87return hasCoinState;
88 }89
90 public State getBeverageSoldState() {91
return beverageSoldState;
92 }93
94 public State getOutOfBeverageState() {95
return outOfBeverageState;
96 }97
98 /* Actions */99 public void insertCoin() {100currentState.insertCoin();
101 }
102
103 public void ejectCoin() {104currentState.ejectCoin();
105 }
106
107 public void selectBeverage() {108currentState.selectBeverage();
109 }
110
111 public void dispense() {112
currentState.dispense();
113 }
114
115 public void releaseBeverage() {116
System.out.println("Beverage comes rolling out the slot!");117
numberOfAvailableBeverages--;118
if (numberOfAvailableBeverages == 0) {119
currentState = outOfBeverageState;120} else {121
currentState = noCoinState;
122
}
123 }
124 }

Now, adding the WINNER state is easy:class BeverageVendingMachine {State noCoinState;State hasCoinState;State beverageSoldState;State outOfBeverageState;State winnerState;public State getWinnerState() {return winnerState;}//also initialize winnerState in constructor}
class WinnerState implements State {public void dispense() {//do lottery and transition to other state}//constructors, instance variables, other action error messages the same}13

Definition of State Pattern
The state pattern allows an object to alter its behavior when its
internal state changes. The object will appear to change its class.

Difference between Strategy and State

Strategy Pattern

State Pattern

The class diagrams of both the patterns are the same, but they differ in their intent.
In general, think of the Strategy Pattern as a flexible alternative to subclassing; if you use inheritance to define thebehavior of a class, then you’re stuck with that behavior even if you need to change it. With Strategy, you can change
the behavior by composing with a different object.
Think of the State Pattern as an alternative to putting lots of conditionals in your context; by encapsulating the
behaviors within state objects, you can simply change the state object in context to change its behavior.

Command Pattern
Example Problem Scenario
Suppose, you are developing a Word Editor. You have Cut, Copy and Delete classes as follows:

Now, you want to develop a Macro operation which would include all the above operations. But the method names arediversified. How would the Macro operation execute the methods in any of the operation classes?
As the Macro class doesn’t know the exact method name of the operation class, we can do the following:
1. Define a common interface method execute() which the Macro class would call on each operation class.
2. As the operation classes don’t implement the execute() method and we don’t want to change the operation
classes, we need to use some sort of adapter classes.
The solution can be as follows (we’ve omitted the Copy operation for brevity):14

4 class Cut {5 void select() {}6 void cut() {}7 void paste() {}8}910 class Delete {11 void select() {}12 void delete() {}13 }14
15 interface Command {16 public void execute();17 }18
19 class CutCommand implements Command {20 private Cut cut;
21
22 public CutCommand(Cut cut) {23
this.cut = cut;
24 }25
26 public void execute() {27
cut.select();28
cut.cut();
29
cut.paste();
30 }
31 }
32
33 class DeleteCommand implements Command {34 private Delete delete;
35
36 public DeleteCommand(Delete delete) {37
this.delete = delete;
38 }39
40 public void execute() {41
delete.select();
42
delete.delete();
43 }
44 }
45
46 class Macro {47 List<Command> commands = new ArrayList<Command>();48
49 public void addOperation(Command command) {50
commands.add(command);51 }52
53 public void executeMacro() {54
for (Command command : commands) {55
command.execute();
56
}
57 }
58 }
59
60 class WordEditor {61 public static void main(String[] args) {62
Macro macro = new Macro();63
macro.addOperation(new CutCommand(new Cut()));
64
macro.addOperation(new DeleteCommand(new Delete()));
65
macro.executeMacro();
66 }
67 }

15

Definition of Command Pattern
The command pattern encapsulates a request as an object, thereby letting you parameterize other objects withdifferent requests, queue or log requests, and support undoable operations.

Uses of Command Pattern
1. Job Queue
2. Logging

Job Queue

Logging16