CS711 - Design Pattern's
CS711 - Design Pattern's
Presented By:
Sheraz Pervaiz
Stuttgart University of Applied Sciences,
Germany
Published By:
www.vumultan.com
“Factory Pattern defines an interface for creating the object but let the subclass decide which
class to instantiate. Factory pattern let the class defer instantiation to the sub class”
We want the user to enter the name in either “first name last name or last name, first name”
format. We have made the assumption that there will always be a comma between last name
and first name and space between first name last names. The client does not need to be worried
about which class is to access when it is entering the name in either of the format. Independent
of the format of the data to be entered, system will display first name and last name.
class Namer {
protected String last; //store last name here
protected String first; //store first name here
public String getFirst(){
return first; //return first name
}
public String getLast() {
return last; //return last name
}
}
Problem Statement:
There is a pizza shop which is offering different delicious pizza's to it' customer. There are some
standard processes which are involved in a pizza creation like first the pizza is prepared by putting
together all the ingredients, then it is prepared for backing, after baking it is cut and put into the
boxes of as per order placed by the customer. There is different type of pizzas like chees, chicken,
vegetable etc; and this list keeps on increasing with addition of in demand pizza and removal of
not in demand pizzas.
Package PizzaFactory;
Public abstract class Pizza {
String name;
String dough;
String sauce;
Void prepare() {
System.out.println(“Preparing:” +name);
System.out.println(“Dough:” +dough);
System.out.println(“Sauce Used:” +sauce);
}
}
“Singleton Design Pattern ensures that there is only one instance of a class and provides global
point of access to it”
Scenario:
In Chocolate manufacturing industry, there are computer-controlled chocolate boilers. The job
of boiler is to take in milk and chocolate, bring them to boil and then pass it on to the next phase
of chocolate manufacturing process. We have to make sure that bad things don’t happen like
filling the filled boiler or boiling empty boiler or draining out unboiled mixture. We have to make
sure that there should be no simultaneous boiler activity taking place.
private ChocolateBoiler() {
empty=true;
boiled=false;
}
public static synchronized ChocolateBoiler getInstance() {
if(uniqueins==null) {
uniqueins=new ChocolateBoiler();
getInstance().fill();
getInstance().boil();
getInstance().drain();
}
return uniqueins;
}
public void fill() {
if(isempty()) {
empty=false;
empty=true;
}
}
public void drain() {
if(!isempty()&&isboiled()) {
empty=true;
}
}
public void boil() {
if(!isempty() && !isboiled()) {
boiled=true;
}
}
public boolean isempty() {
return empty;
}
public boolean isboiled() {
return boiled;
}
}
Virtual University of Pakistan | www.vumultan.com
CS711 – Software Design 11
Shallow Copy
package ShallowCopy;
class Car {
private String name;
public String getName() {
return name;
}
public void setName(String s) {
name = s;
}
public Car(String s) {
name = s;
}
}
Deep Copy
class Car {
private String name;
public String getName() {
return name;
}
public void setName(String s) {
name = s;
}
public Car(String s) {
name = s;
}
}
System.out.println(p.getCar().getName());
Person q = (Person) p.clone(); //Clone as a shallow copy
System.out.println("Clone (before change): " + q.getName() + " - "
+ q.getCar().getName());
q.setName("Person-B"); //change the primitive member
q.getCar().setName("Accord"); //change the lower-level object
System.out.println("Clone (after change): " +q.getName() + " - "
+q.getCar().getName());
System.out.println("Original (after clone is modified): " + p.getName() + " - "
+ p.getCar().getName());
}
}
OUTPUT
Original (orginal values): Person-A
Civic
Clone (before change): Person-A - Civic
Clone (after change): Person-B - Accord
Original (after clone is modified): Person-A - Civic
Example:
A computer user in a typical organization is associated with a user account. A user account can
be part of one or more groups. Permissions on different resources (such as servers, printers, etc.)
are defined at the group level. A user gets all the permissions defined for all groups that his or
her account is part of. Let us build an application to facilitate the creation of user accounts.
For simplicity, let us consider only two groups — Supervisor and AccountRep —
representing users who are supervisors and account representatives, respectively and we have
defined permissions in text files for each user group.
AccountPrototypeFactory factory =
new AccountPrototypeFactory(supervisor, AccountRep);
/* Using protype objects to create clones of user accounts */
UserAccount newSupervisor = factory.getSupervisor();
// Cloning is performed using existing factory object
newSupervisor.setUserName("Ali");
newSupervisor.setPassword("canvas");
System.out.println(newSupervisor);
UserAccount anotherSupervisor = factory.getSupervisor();
anotherSupervisor.setUserName("Asim");
anotherSupervisor.setPassword("temp");
System.out.println(anotherSupervisor);
UserAccount newAccountRep = factory.getAccountRep();
newAccountRep.setUserName("Ahmad");
newAccountRep.setPassword("Pakistan");
System.out.println(newAccountRep);
}
Virtual University of Pakistan | www.vumultan.com
CS711 – Software Design 16
Example:
Consider construction of a home, Home is the final end product (object) that is to be returned as the
output of the construction process. It will have many steps, like basement construction, wall construction
and so on roof construction. Finally the whole home object is returned. Here using the same process you
can build houses with different properties. Each house is having same construction steps but the output
may be different depending upon the requirements of the house but the end product is home in any case.
We need to write programs which simulate this process.
package BuildingHouse;
public interface HousePlan {
public void setBasement(String basement);
public void setStructure(String structure);
public void setRoof(String roof);
public void setInterior(String interior);
}
• Target - defines the domain-specific interface that Client uses. This class is visible to the client
and client will interact or pass request to this class.
• Adapter - adapts the interface Adaptee to the Target interface.
• Adaptee - defines an existing interface that needs adapting.
• Client - collaborates with objects conforming to the Target interface.
“Façade provides a unified interface to a set of interfaces in a subsystem. It defines a higher-level interface
which is easier to use”
Problem Statement:
For a typical online transaction oriented system, customer can perform transactions against an account
i-e Pay pal etc; credit card validators are used for verifying the creditionals of a client submitted by the
client for checkout purposes. Address of the customer is also stored and checked for data entry checks
for shipment purposes. Usually account, address and credit card subsystems works together to provide
the feature of online transaction.
“Composite Design pattern allow us to compose objects into tree structures to represent whole-part
hierarchy. It let the client handle the composite and individual components in a uniform manner”
package composite;
public abstract class FileSystemComponent {
String name;
public FileSystemComponent(String cName) {
name = cName;
}
public void addComponent(FileSystemComponent component) throws CompositeException {
throw new CompositeException("Invalid Operation. Not Supported");
}
public FileSystemComponent getComponent(int componentNum) throws CompositeException {
throw new CompositeException("Invalid Operation. Not Supported");
}
public abstract long getComponentSize();
} //End of class FileSystemComponent
package composite;
import java.util.Vector;
public class DirComponent extends FileSystemComponent {
Vector dirContents = new Vector();
//individual files/sub folders collection
public DirComponent(String cName) {
super(cName);
}
public void addComponent(FileSystemComponent fc) throws CompositeException {
dirContents.add(fc);
}
public FileSystemComponent getComponent(int location) throws CompositeException {
return (FileSystemComponent) dirContents.elementAt(location);
}
public long getComponentSize() {
long sizeOfAllFiles = 0;
Enumeration e = dirContents.elements();
while (e.hasMoreElements()) {
FileSystemComponent component = (FileSystemComponent) e.nextElement();
sizeOfAllFiles = sizeOfAllFiles + (component.getComponentSize());
}
return sizeOfAllFiles;
}
} //End of class
try {
mainFolder.addComponent(subFolder1);
mainFolder.addComponent(subFolder2);
subFolder1.addComponent(folder1File1);
subFolder1.addComponent(folder1File2);
subFolder2.addComponent(folder2File1);
subFolder2.addComponent(folder2File2);
} catch (CompositeException ex) {
//
}
//Client refers to both composite & //individual components in a uniform manner
“Facilitates the reuse of many fine-grained objects, making the utilization of large numbers of objects
more efficient”
Description of Classes:
1. Flyweight - Declares an interface through which flyweights can receive and act on extrinsic state.
2. Concrete Flyweight - Implements the Flyweight interface and stores intrinsic state. A Concrete
Flyweight object must be sharable. The Concrete flyweight object must maintain state that it is
intrinsic to it, and must be able to manipulate state that is extrinsic.
3. Flyweight Factory - The factory creates and manages flyweight objects. In addition the factory
ensures sharing of the flyweight objects. The factory maintains a pool of different flyweight
objects and returns an object from the pool if it is already created, adds one to the pool and
returns it in case it is new.
4. Client - A client maintains references to flyweights in addition to computing and maintaining
extrinsic state
Example:
We need to design for a war game in which there is a large number of soldier objects; a soldier object
maintains the graphical representation of a soldier, soldier behavior such as motion, and firing weapons,
in addition soldier’s health and location on the war terrain. Creating a large number of soldier objects is a
necessity however it would incur a huge memory cost.
Note that although the representation and behavior of a soldier is the same their health and
location can vary greatly. The war game instantiates 5 Soldier clients, each client maintains its internal
state which is extrinsic to the soldier flyweight, although 5 clients have been instantiated only one
flyweight Soldier has been used.
/** Note that this method accepts soldier location. Soldier Location is Extrinsic and no
reference to previous location or new location is maintained inside the flyweight
implementation */
public void moveSoldier( int previousLocationX, int previousLocationY,
int newLocationX, int newLocationY) {
/** delete soldier representation from previous location then render soldier
representation in new location*/
}
}
public class SoldierFactory { /** Pool for one soldier only, if there are more soldier types
this can be an array or list or better a HashMap */
private static Soldier SOLDIER; /** * getFlyweight * @return */
public class SoldierClient { /** This is the "Heavyweight" soldier object which is the client of the flyweight
soldier this object provides all soldier services and is used in the game */
private Soldier soldier = SoldierFactory.getSoldier(); /**Reference to the flyweight */
private int currentLocationX = 0; /** This state is maintained by the client */
private int currentLocationY=0; /** This state is maintained by the client */
Intent
The intent of this pattern is to provide a Placeholder for an object to control references to it.
“Proxy design pattern provides a surrogate or placeholder for another object to control access to it”
Example:
Consider an image viewer program that lists and displays high resolution photos. The program has to show
a list of all photos however it does not need to display the actual photo until the user selects an image
item from a list.
The code below shows the Image interface representing the Subject. The interface has a single method
showImage() that the Concrete Images must implement to render an image to screen.
package proxy;
public interface Image { /** * Subject Interface */
public void showImage();
}
// assume that the user selects image two item from images list
highResolutionImageNoProxy2.showImage();
// note that in this case all images have been loaded into memory
// and not all have been actually displayed
// this is a waste of memory resources
}
}
“The Iterator Design pattern provides a way to access the element of aggregate object sequentially
without knowing its underlying representation”
Example:
This example is using a collection of books and it uses an iterator to iterate through the collection. The
problem is to store the books in the form of collection and then the items from the collections are needed
to be retrieved from the container consistently.
interface IIterator {
public boolean hasNext();
public Object next();
}
interface IContainer {
public IIterator createIterator();
}
“This pattern defines a one-to-many relationship between objects so that when there is change in the
state of the one object it should be notified and automatically update it all dependent”.
1. Subject: This class will keep track of its observers and provides an interface for attaching and
detaching Observer objects
2. Observer: It defines an interface for update notification
3. Concrete Subject: As discussed, the object being observed will be object of this class, it stores state
of interest to Concrete Observer objects. Its responsibility includes sending a notification to its
observers when its state changes
4. ConcreteObserver: This is object of class who is observing the subject class i-e the observing object.
This class stores state that should stay consistent with the subject's by implementing the Observer
update interface to keep its state consistent with the subject's
1. Abstract Class: This class defines abstract primitive operations that concrete subclasses define to
implement steps of an algorithm.
2. Concrete Class: This class implements the primitive operations to carry out subclass-specific steps
of the algorithm.
Example:
Lets' assume we have to develop an application for a travel agency. The travel agency is managing each
trip. All the trips contain common behavior but there are several packages. For example, each trip contains
the basic steps:
1. The tourists are transported to the holiday location by plane/train/ships.
2. Every day they are visiting some place.
3. They are returning back home.
Our task is to design and implement a system which should simulate the mentioned requirements.
public class Trip { // This method can’t be overridden by the sub class but we are calling abstract method inside it.
//This will keep intact the outline of the algorithm.
public final void performTrip() {
doComingTransport();
doDayA();
doDayB();
doDayC();
doReturningTransport
}
public abstract void doComingTransport();
public abstract void doDayA();
public abstract void doDayB();
public abstract void doDayC();
public abstract void doReturningTransport();
}
public class PackageA extends Trip {
public void doComingTransport(){
System.out.println("The tourists are comming by air ...");
}
public void doDayA() {
System.out.println("The tourists are visiting the garden ...");
}
public void doDayB() {
System.out.println("The tourists are going to the museum ...");
}
1. Memento: This class stores internal state of the Originator object. The state can include any
number of state variables. The Memento must have two interfaces, an interface to the caretaker.
This interface must not allow any operations or any access to internal state stored by the memento
and thus honors encapsulation. The other interface is to the originator and allows the originator to
access any state variables necessary to for the originator to restore previous state.
2. Originator: It creates a memento object capturing the originators internal state; it then uses the
memento object to restore its previous state.
3. Caretaker: This class is responsible for keeping the memento. The memento is opaque to the
caretaker, and the caretaker must not operate on it.
Example:
Let's use a simple example in Java to illustrate this pattern. As it's a pattern used for undo frameworks, we'll
model a editor. First, the memento needs to be able to save editor contents, which will just be plain text:
// Now our Originator class, the editor, can use the memento:
//Originator Class
“It encapsulates a request as an object thereby letting you parameterize other objects with different
requests queue or log request and support undoable operations”
Example:
In stock exchange, the client creates some orders for buying and selling stocks (ConcreteCommands). Then
the orders are sent to the agent (Invoker). The agent takes the orders and place them to the StockTrade
system (Receiver). The agent keeps an internal queue with the order to be placed. Let's assume that the
StockTrade system is closed each Monday, but the agent accepts orders, and queue them to be processed
later on.
class StockTrade {
public void buy() {
System.out.println("You want to buy stocks");
}
public void sell() {
System.out.println("You want to sell stocks ");
}
}
class Agent {
private m_ordersQueue = new ArrayList();
public Agent() {
}
void placeOrder(Order order) {
ordersQueue.addLast(order);
order.execute(ordersQueue.getFirstAndRemove());
}
}