Unit 4
Unit 4
Unit 4
Unit
DESIGN PATTERNS
GRASP
The GRASP is a tool that helps to master the basics of OOD and understanding
responsibilities.
GRASP is a learning aid that helps to understand the essential object design and apply the
design in a methodical, rotational and explainable way.
RDD
RDD is a general metaphor for thinking about object oriented design.
It means low grasping of these principles to successfully design object oriented software.
While coding or drawing interaction and class diagrams, developers apply the ideas
behind GRASP to master the principles of object oriented design.
4.2 CREATOR
Problem
One of the most common activities in object oriented system is creation of objects.
General principle is applied for the assignment of creation responsibilities.
Design supports
• Low coupling
• Increased clarity
• Encapsulation
• Reusability
Solution
If B is a creator of A objects then atleast one of the following must be true.
• B contains A
• B compositely aggregates A
• B records A
• B closely uses A
Design Patterns 4.3
• B is an expert while creating A (B passes the initializing data for A that is passed to A
when created).
If more than one option is true.
Class B aggregates or contains class A.
Example
NEXTGen POS Application
We have to find who is the creator of SalesLineItem instance.
Consider the partial domain model of SaleLineItem.
The common task of creator is to assign responsibilities related to the creation of objects.
All common relationships between classes are
• Composite aggregates part
4.4 Object Oriented Analysis and Design
• Container contains content
• Recorder records
Enclosing container or recorder is good for creating the thing contained or recorded.
Composition is also considered for creator.
Initialization during creation is done by some method like Java constructors.
Example: ‗Payment‘ instance while creation initialized with ‗Sale‘ total.
‗Sale‘ is a candidate creator of ‗Payment‘.
Contradictions:
Based on some external value, creation requires complexity like
• Recycled instances for performances.
• Creating an instance from one of a family of similar classes based an external property
etc.
• Abstract factory or
• Concrete façade
Then use the class of creator.
Benefits
• Lower maintenance due to low coupling
• Higher opportunities for reuse
After adding the getTotal( ), the partial interaction and class diagrams given as
After knowing and answering subtotal, a SalesLineItem has to know product price.
Contradictions
Solution of expert is not desirable in some cases due to problems of coupling and
cohesion.
To overcome this
• Keep application logic in one place [like domain software objects]
• Keep database objects in another place [separate persistence services subsystem]
Separation of major concerns improves coupling and cohesion in a design.
Benefits
1) Information encapsulation use their information to fulfill tasks.
2) High cohesion is supported
Types of coupling
There are 2 types of coupling
1) Low coupling or weak coupling
2) High coupling or strong coupling
Low coupling
An element if does not depend on too many other elements like classes, subsystems
systems it is having low coupling.
High coupling
A class with high coupling relies on many other classes.
Design 1:
Suggested by creator
1) Register instance send addpayment message to sale, passing newPayment as a
parameter.
2) Register class couples with payment class and creates payment.
Low coupling
1) Assigns responsibility that will not yield negative results that cause high coupling.
2) Support design of independent classes.
Classes that are
1) Generic in nature
2) Having high probability of reuse will have low coupling. Extreme case of low
coupling is no coupling between classes.
That is not desired because a moderate degree of coupling between the classes is
normal and is necessary for creating an object oriented system.
High coupling to stable elements is seldom a problem.
Benefits
• Not affected by changes in other components
• Simple to understand in isolation
• Convenient to reuse
Design 1
• Register records a payment in real world
4.10 Object Oriented Analysis and Design
• Then it sends addpayment message to sale, passing newpayment as a parameter.
High cohesion is
• Easy to maintain
• Understand and
• Reuse
Modular design
―Modularity is the property of system that has been decomposed into a set of cohesive and
loosely coupled modules‖.
Modular design creates methods and classes with single purpose, clarity and high
cohesion.
4.6 CONTROLLER
A controller is defined as the first object beyond the user interface (UI) layer that is
responsible for the receiving or handling a system operation message.
Example:
1) A cashier is POS terminal pressing ―EndSale‖ button indicating ―sale has ended‖
2) Writer using word processor presses ―spell check‖ button to perform checking of
spelling
Solution
Assign responsibility to one of the following
• Represents overall ―system‖, ―a root object‖
◦ These are variations of façade controller.
• Represents a usecase scenario called
◦ <usecaseName> handler
4.12 Object Oriented Analysis and Design
◦ <usecaseName> coordinator or
◦ <usecaseName> session
Here we use some controller class for all system events in same usecase scenario.
A session is an instance of a conversation with an actor.
Example:
NextGen application contains several system operations.
Controllers
The facade controller represents the overall system, device or a sub system.
Choose some class name that suggests a cover or faced over other layers of the application
that provides main service calls from UI layer down to the other layers.
In used case controller there is a different controller for each use case. Facade controllers
lead to low cohesion or high coupling design.
So usecase controllers are good when there are many system events across different
processes.
• Boundary objects
• Entity objects
• Control objects
System operations should be handled in application logic or domain layer of objects rather
than UI layer of a system.
Code
package.com.nextgen.ui.swing;
//import
public class ProcessSaleJFrame extends JFrame
{
//window refers to ‗controller‘ domain object
(1) private Register register
public ProcessSaleJFrame (Register-register)
{
register = -register;
}
private JButton BTN_ENTER_ITEM /* this button is clicked to perform sys operation
―enetrItem‖*/
———
———
———
(2) BTN_ENTER_ITEM.addActionListener (new ActionListener ( )
{
public void actionPerformed (ActionEvent e)
{
// utility class
———
———
(3) register.enterItem(id, qty);
}
}); // end of ActionListerner
return BTN_ENTER_ITEM;
}// end of method
———
}
4.16 Object Oriented Analysis and Design
Code:
package.com.nextgen.ui.web;
//import
public class EnterItemAction extends Action
{
public ActionForward execute (ActionMapping mapping,
ActionForm form, HttpServletRequest request, HttpServlet Response response)
throws exception
———
———
(1) Register register = repository.getRegister ( );
———
———
(2) register.enterItem (id, qty);
}// end of method
} // end of class
A controller class has low cohesion i.e. unfocused and handling many responsibilities. It is
called bloated controller.
• When facade controller is chosen, a single controller class receives all system events.
• Violating information expert and high cohesion controller itself performs many of the tasks.
• Controller has many attributes.
These are signs of bloated controller.
Related patterns
• Command Each message is a command object
• Facade Facade controller is kind of facade
• Layers Domain logic in domain layer than presentation layer
• Pure fabrication A use case controller
Example:
The getProductDescription message sent from a Register to a product catalog means that
ProductCatalog instance is visible to register.
Motivation of visibility
For an object A to send a message to an object B, B must be visible to A.
Attribute visibility
• It is a permanent visibility.
• Attribute visibility from A to B exists if B is attribute of A.
• It persists as long as A and B exists
Example
Register has attribute visibility to ProductCatalog, because it is an attribute to Register.
Example:
When makeLineItem is sent to a sale instance, a ProductDescription instance is passed as
a parameter.
4.20 Object Oriented Analysis and Design
Local visibility
It exists from A to B when B is declared as a local object within a method of A.
It persists only within the scope of the method. So it is relatively temporarily visible.
The local visibility is achieved by
• Creating a new local instance and assigning to a local variable
• Assign the returning object from a method invocation to a local variable.
Advantages of factory
(i) Separate the responsibility of complex creation into cohesive helper objects.
(ii) Potential complex creation is hidden.
(iii) Performance-enhancing memory management strategies such as object catching or
recycling are allowed.
Strategies such as object catching or recycling is allowed.
4.22 Object Oriented Analysis and Design
Name : Factory
Problem : For complex creation logic, for better cohesion who is responsible for creating
objects.
Solution : A pure fabrication object called ‗factory‘ is created that handles creation.
In ‗Service Factory‘, the logic to decide the class creation is resolved by reading
in the class name from external source.
This is called ―datadriven design‖
4.9 ADAPTER
Name : Adapter
Problem : If similar components have different interfaces then how to resolve
incompatible interfaces.
Solution : Using an intermediate adapter object, convert original interface of a
component to another interface.
The NextGen POS system supports many third party services like,
• Tax calculators
• Credit authorization services
• Inventory systems
• Accounting systems etc
Add a level of indirection with objects to adapt to the solution.
Design Patterns 4.23
The motivation to call resource adapter exist when wrapping objects provide adaptation.
Example in java
public static synchronized ServiceFactory getInstance ( )
{
if (instance ==null)
{
//critical sec in Multithreaded application
instance = newServicesFactory ( );
}
return instance;
}
Eager initialization
public class servicesFactory
{
//eager initialization
private static servicesFactory instance = new ServicesFactory ( ); public static
servicesFactory getInstance ( ) {
Return instance;
}
// other methods…
}
:Register
:ServiceFactory
aa=getAccounting Adapter
The ‗1‘ indicates that invisibility to this is achieved by singleton pattern
Design Patterns 4.27
The model-view separation principle discourages such solutions. It states that ―Model‖
objects should not know about view or presentation objects such as window.
Due to low coupling the replacement of the view or presentation layer by a new one or of
particular windows by new windows.
The variations are supported by model view separation.
Design Patterns 4.29
To solve this problem observe patterns are used.
Applying UML
The OnPropertyEvent message is polymorphic in the above interaction diagram.
Coupling to generic interface need not be present, which can be dynamically added or
removed supports low coupling.
• Alarm windows
• Four beepers
• One reliability WatchDog
The OnAlarmEvent notifies eight of these AlarmListeners when event happens.
Implementation
Events:
In java and C#.NET implementation of observer, ‗event‘ is shown as regular message such as
onPropertyEvent.
In these cases, the event is defined as class and filled with event data.
Example:
class PropertyEvent extends Event
{
private object sourceOfEvent;
private string propertyName;
private object oldvalue;
private object newvalue;
//…
}
Design Patterns 4.33
Java
In 1996, the observable-observer design was replaced by Java Delegation Event Model
(DEM) version of publish-subscribe.
Message 1:
Message 2:
Example:
Sale must contain many SalesLineItem instances.
In Java List and Map interfaces are represented by ArrayList and HashMap.
4.38 Object Oriented Analysis and Design
The requirements for collection class are
(i) Key based lookup of a map
(ii) Ordered list requires a List.
LinesItems is described in terms of interface.
Private List LineItems = new ArrayList ( );
Sale.makeLineItem method
Example:
First classes payment/product Description is implemented.
Next Product catalog / SaleLineItem are implemented.
Possible order of class Implementation and testing
The rhythm is to write a little test code, then write production code, make it pass the test
write some more test code and so forth.
Class Payment
//all classes in package
package com too.nextgen.domain;
public class Payment
{
private money amount;
public Payment (Money cash tendered)
{
amount = cashTendered;
}
public Money getAmount ( )
{
return amount;
}
class Productcatalog:
{
private Map<ItemID, ProductDescription>
description = newHashMap ( )
<ItemID, ProductDescripion>;
public ProductCataglog( )
{
// Sample Data
ItemID id1 = new ItemID (10);
ItemID id2 = new ItemID (20);
money price = new Money (3);
product Description d;
d = new Product Description (id1, price, ‗Product 1‘);
description put (id1, d);
Design Patterns 4.41
d = new Product Description (id2, price, ‗Product 2‘);
description put (id2, d);
}
public Product Description getProductDescription (ItemID id)
return description get (id);
}
class Register:
public class Register
{
private Product Catalog Catalog;
private Sale currentSale;
public Register (ProductCatalog Catalog)
{
this.catalog = catalog;
}
public void endSale ( )
{
currentSale.become Complete ( );
}
public void enterItem (ItemID id, int quantity)
{
productDescription desc = catalog.getProductDescription (id);
currentSale.makeLineItem (desc, quantity);
}
public void makeNewSale ( )
{
currentSale = newSale ( );
}
public void makePayment (Money cashTendered)
{
currentSale.makePayment( cashTendered);
}
}
4.42 Object Oriented Analysis and Design
class Productdescription
public class ProductDescription
{
private ItemID id;
private Money price;
private String descripiton;
public ProductDescription
(ItemID id, Money price, string descriptio )
{
this.id = id;
this.price = price;
this.description = description;
}
public ItemID getItemID ( ) {return id;}
public Money getPrice ( ) {return price;}
public string getDescription {return description;
}
class Sale:
public class Sale
{
private List <SalesLineItem> lineItems = new ArrayList ( ) <SalesLineItem>;
private Date date = new Date ( );
private Boolean is complete = false;
private Payment Payment;
public Money getbalance ( )
{
return Payment getAmount ( ).minus (getTotal( ));
}
public void become Complete ( ) {isComplete = true;}
public Boolean is complete ( ) {return is complete;}
public void makeLineItem (Product description desc, int quantity)
{
linesItems.add (new SalesLinesItem (desc, quantity));
Design Patterns 4.43
}
public Money getTotal ( )
{
Money Total = new Money ( );
Money subtotal = null;
for (SalesLineItem lineItem : lineItem)
{
subtotal = lineItem.getsubtotal ( );
total.add (subtotal);
}
return total;
}
public void makePayment (Money cashTendered)
{
payment = new Payment (cash Tendered);
}
}
class SalesLineItem
public class SalesLineItem
{
private int quantity;
private ProductDescription description;
public SalesLineItem (Product Description desc, int quantity)
{
this.description = d; this.quantity = quantity;
}
public Money getsubtotal ( )
{
return description.getPrice ( ).times (quantity);
}
}
class store
public class store
4.44 Object Oriented Analysis and Design
{
private ProductCatalog catalog = new Product Catalog( );
private Register register = new Register(Catalog);
public Register getRegister ( )
{return register;}
}
Class Square
//all classes are in the package
package.com.too.monopoly.domain;
public class square
{
private string name;
private square nextsquare;
private int index;
public square (string name, int index)
{
this.name = name; this.index = index;
}
public void setNextSquare (square S)
{
nextSquare = S;
}
public Square getnextSquare ( )
{
return nextSquare;
}
public string getname ( )
{
return name;
}
public int getIndex ( )
{
return index;
}
Design Patterns 4.45
}
Class Piece
public class Piece
{
private Square location; public Piece (Square location)
{
this.location = location;
}
public Square getLocation ( )
{
return location;
}
public void setLocation (Square location)
{
this.location = location;
}
}
Class Die
public class Die
{
public static final int MAX = 6; private int faceVlaue;
public Die ( )
{
roll ( );
}
public void roll ( )
{
faceValue = (int) ((Math.random ( ) * MAX) + 1);
}
public int getfaceValue ( )
{
return faceValue
}
}
4.46 Object Oriented Analysis and Design
Class Board
public class Board
{
private static final int SIZE = 40;
private List squares = new ArrayList (SIZE);
public Board ( )
{
build squares ( );
link Squares ( );
}
public Square getSquare (Square start, int distance)
{
int endIndex = (start.getIndex( ) + distance) %size;
return (Square) Square.get (endIndex);
}
public Square getstartSquare ( )
{
return (Square) Squares.get (0);
}
private void bulidSquare ( )
{
for (int i=1 i<=SIZE; i++)
{
build (i);
}
}
private void build (int i)
{
Square S = new Square (―Square‖ +I, i-1);
Square.add(S);
}
private void linkSquare ( )
{
Design Patterns 4.47
for (int i=0;i<(SIZE-1); i++)
{
link (i);
}
Square first = (square) Square.get(0);
Square last = (square) Square.get(SIZE-);
last.setNextSquare (first);
}
private void link (int i)
{
Square current = (Square) Squares.get(i);
Square next = (Square) Squares.get(i+1);
current.setNextSquare (Next);
}
}
Class player
public class player
{
private string name;
private Piece piece;
private Board board;
private Die [ ] dice;
public player (string name, Die [ ] dice, Board board)
{
this.name = name;
this.dice = dice;
this.board = board;
piece = new Piece (board.getstartsquare ( ));
}
public void take turn ( )
{
int roll Total = 0;
4.48 Object Oriented Analysis and Design
for (int i =0; i<dice.length; i++)
{
dice [i].roll ( );
rollTotal += dice[i].getFaceVlaue ( );
}
Square newLoc = board.getSquare (Piece.getLoaction ( ), rollTotal);
piece.setLocation(newLoc);
}
public square getLocation ( )
{
return piece.getLocation ( );
}
public string getName ( )
{
return name;
}
}