You are on page 1of 87

Introduction to Object Oriented Design

Analysis Phase Revisited


Defining use cases Use case diagram System sequence diagram Conceptual Model (Analysis Class Diagram) CRC Cards Operation Contracts State Diagrams

Analysis Artifact Use Cases

Questions Answered What are the domain processes?

Conceptual Model (Analysis Class Diagram) System Sequence Diagram Contracts

What are the concepts and terms?

What are the system events and operations? What do the system operations do?

Activities Carried out in OOD


Develop real use cases Drawing interaction diagrams
Sequence / collaboration diagrams

Assigning responsibility to objects


Grasp Patterns GoF Patterns

Determining visibility Drawing design class diagrams Deciding on architectural issues Logical Architecture and UML Package Diagram

Logical Architecture, Layers and partitions


The logical architecture is the large scale organization of the software classes into packages (or namespace), subsystems and layers.
It is called logical architecture because at this stage there is no decision about how these elements are deployed across different operating systems processes or across physical computers in the network.

A layer is a very coarse grained grouping of classes, packages, or subsystems that has cohesive responsibility for the major part of the system Typical layers in an OO system includes
User interface Application logic and domain objects Technical service

The layers of an architecture represent vertical slices, while partitions represent a horizontal division of the relatively parallel subsystems of a layer.

Model View Separation Principle


MVS Principle states that model objects should not have direct knowledge of view objects (User Interface).

Relationship between SSD and Layers


SSD illustrates specific system operation but hide specific UI layer of the system that captures this system operation requests. UI objects actually delegates these requests to the domain layer for handing.

UI Swing :System Cashier makeNewSale() : Cashier enterItem(id, quantity) description, total Domain endSale() ... makeNewSale() enterItem() endSale() ... ProcessSale Frame makeNewSale() enterItem() endSale()

Register makeNewSale() enterItem() ...

the system operations handled by the system in an SSD represent the operation calls on the Application or Domain layer from the UI layer

An UML Package Diagram


UI not the Java Swing libraries, but our GUI classes based on Swing Swing Web

Vertical Layers

Domain

Sales

Payments

Taxes

Technical Services

Persistence

Logging

RulesEngine

Horizontal Partitions

Developing Real Use cases


A real use case describe the real or actual design of the use case in terms of concrete input and output technology and its over all implementation Diagrams, story boards, Interface widgets (window objects)

Widget for the Enter Item System Event under Process Sale use case

Connecting User Interface (View) and Domain Layer (Model)

presses button

Cashier actionPerformed( actionEvent ) :ProcessSale JFrame 1: enterItem(id, qty) system event

UI Layer

Domain Layer

:Register

Connecting User Interface (View) and Domain Layer (Model)

presses button

Cashier actionPerformed( actionEvent )

UI Layer

:ProcessSale JFrame

3: t = getTotal

1: enterItem(id, qty) 2 [no sale] : s = getSale : Sale

Domain Layer

:Register

s : Sale

Drawing Interaction Diagrams


Interaction Diagrams
Collaboration diagrams Sequence diagrams

Drawn on the basis of conceptual model (analysis class diagram) Show the choices in assigning responsibility to objects Decision for assigning the responsibilities are based on the flow of massages between the interacting objects. Use of patterns

Responsibilities and Methods


Responsibility is defined as a contract or obligation of a type or a class Responsibilities are related to the obligations of an object in terms of its behaviour Two types of responsibility
Doing
Doing something itself Initiating action in other objects Controlling or coordinating the activities in other objects

Knowing
Knowing about private encapsulated data Knowing about related objects Knowing about the things it can derive or calculate

Ex: Sale is responsible for printing itself (doing) Sale is responsible for knowing its date

Sequence Diagram
: Register : Sale

makePayment(cashTendered) makePayment(cashTendered) create(cashTendered) : Payment

Collaboration Diagram
direction of message

makePayment(cashTendered)

:Register

1: makePayment(cashTendered)

:Sale

1.1: create(cashTendered)

:Payment

What are Design Patterns


A design pattern is usually defined as a common solution to a recurring problem in a given context. It specifies the structure and behaviour of a society of classes Usually presented as a problem and solution pair Never convey a new idea have a name for ease of communication Grasp patterns (Larman) GoF Patterns (Gamma et al.)

Grasp Patterns (Five basic patterns)


Creator Information Expert High Cohesion Low Coupling Controller

Creator
Problem: Who should be responsible for creating a new instance of some class? Solution: Assign class B the responsibility to create an instance of class A if one of the following is true
B aggregates A objects (Whole-part relationship) B Contains A objects B records instances of A objects B closely uses A objects B has the initializing data that will be passed to A when it is created (B is an expert with respect to A)

Sale date time 1

Contains 1..*

SalesLineItem quantity

* Sale aggregates many SalesLineItem objects. Create Pattern suggest that sale is a good candidate to have the responsibility of creating it described by 1 Product Spec description price code

Partial Conceptual Model

Sale : Register MakeLineItem(quantity) date time total() MakeLineItem()

: Sale

SalesLineItem quantity 1: Create(quantity) subtotal()

sli: SaleLineItem

Information Expert
Problem: What is a general principle of assigning responsibilities to objects? Solution: Assign the responsibility to the information expert- the class that has information necessary to fulfill the responsibility.

Sale time 1 Contains 1..* Sales LineItem quantity

Partial Conceptual Model

Described-by

Product Description description price itemID

t = getTotal

:Sale time ... New method

Sale

getTotal()

this notation will imply we are iterating over all elements of a collection

t = getTotal

: Sale

1 *: st = getSubtotal

lineItems[ i ] : SalesLineItem

Sale time ... getTotal) (

SalesLineItem quantity New method getSubtotal ()

t = getTotal

: Sale

1 *: st = getSubtotal

lineItems[ i ] : SalesLineItem

1.1: p := getPrice() Class Sale SalesLineItem Responsibility Knows Sales Total Knows line item sub total :Product Description

ProductDescription Knows product price Product Description SalesLineItem quantity getSubtotal() New method getPrice () description price itemID

Sale time ... getTotal()

Low Coupling
Problem: How to support low dependency and increase reuse? Solution: assign a responsibility so that coupling remains low.
A class with weak coupling does not depend on too many other classes

1: create() p : payment

Design 1
makePayment() 2: addPayment(p) : Register :Sale

1: makePayment() :Sale

Design 2
(Low Coupling) makePayment() : Register

1.1:create() p : payment

High Cohesion
Problem: How to keep objects focused, understandable, and manageable, and as a side effect, support Low Coupling? Solution: Assign a responsibility so that cohesion remains high. Use this to evaluate alternatives.

What first object beyond the UI layer receives and coordinates (controls) system operation? Assign the responsibility for handling a system event to a class representing one of the following choices
Represents the overall system (Faade Controller) Represents over all business organization (Faade controller) Represents something in the real world that is active (For example, the role of a person) that might be involved in the task (role controller) Represents an artificial handler of all system events of a use case (use case/session controller)

Controller

System Operations: Major input event generated by external actor Controller: is a non-user interface object responsible for handling a system event

presses button

: Cashier actionPerformed( actionEvent )

UI Layer

:SaleJFrame system operation message enterItem(itemID, qty)

Domain Layer

: ???

Which class of object should be responsible for receiving this system event message? It is sometimes called the controller or coordinator. It does not normally do the work, but delegates it to other objects. The controller is a kind of "facade" onto the domain layer from the interface layer.

Choices for Controller:


Represents overall system : Register, POSSystem
Facade Controller: Few system events

Represents the business organization : Store


Facade Controller: Few system events

Represents something active in the real-world: Cashier


Roll controller: All the responsibilities of a single real-world object

Artificial handler of a use case containing the system operation : ProcessSaleHandler


UseCase Controller: Too many system events

Choice of the most appropriate controller depends on the factors like cohesion and coupling.

enterItem(id, quantity)

:Register

enterItem(id, quantity)

:ProcessSaleHandler

System endSale () enterItem () makeNewSale () makePayment () makeNewReturn () enterReturnItem () ... ...

Register

endSale () enterItem () makeNewSale () makePayment () makeNewReturn () enterReturnItem () ...

system operations discovered during system behavior analysis

allocation of system operations during design , using one facade controller

System endSale () enterItem () makeNewSale() makePayment() enterReturnItem() makeNewReturn() ... ...

ProcessSale Handler ...

HandleReturns Handler

endSale () enterItem () makeNewSale() makePayment ()

enterReturnItem () makeNewReturn () ...

allocation of system operations during design , using several use case controllers

Bloated Controller
A Controller handling too many responsibilities (Low Cohesion) Sign of Bloated Controller
A single controller receiving all system events, Low cohesion Too many attributes

Solution
More controller Single controller that delegates the responsibility to other objects

enterItem interaction diagram (Dynamic View)


by Controller by Creator

enterItem(id, qty) :Register

2: makeLineItem(desc, qty) :Sale

1: desc = getProductDesc(id)

2.1: create(desc, qty) :Product Catalog sl: SalesLineItem

by Expert

1.1: desc = get(id) 2.2: add(sl) : Map<ProductDescription> lineItems : List<SalesLineItem>

add the newly created SalesLineItem instance to the List

Partial Design Class Diagram (DCD) related to enterItem design


ProductDescription ProductCatalog 1 catalog ... getProductDesc(...) ... description 1 Sale Register ... enterItem(...) ... currentSale 1 makeLineItem(...) ... isComplete : Boolean time : DateTime lineItems {ordered} 1..* SalesLineItem quantity : Integer ... descriptions description : Text {Map} price : Money 1..* itemID: ItemID

Completion of item entry -endSale Interaction Diagram


endSale( 1: becomeComplete

:Register

s :Sale

by Controller

by Expert

sale.getTotal Interaction Diagram


by Expert by Expert UML: note the selector notation to select elements from the lineItems collection

tot = getTotal

:Sale

1 * [i = 1..n]: st = getSubtotal

lineItems[ i ]: SalesLineItem 1.1: pr = getPrice

:ProductDescription

Showing a method in a note symbol


method public void getTotal() { int tot = 0; for each SalesLineItem, sli tot = tot + sli.getSubtotal(); return tot }

tot = getTotal

:Sale

1 *[ i = 1..n]: st = getSubtotal

lineItems[ i ] : SalesLineItem 1.1: pr = getPrice

:ProductDescription

register.makePaymant Interaction Diagram


by Controller by Creator and Low Coupling

makePayment(cashTendered)

:Register

1: makePayment(cashTendered)

:Sale

1.1: create(cashTendered) :Payment

Logging a sale
Sale ... ... ... ... Sale

*
Logs-completed5 1 Store ... addSale(s : Sale) ... ... Logs-completed5

*
1 SalesLedger

addSale(s : Sale) ...

Store is responsible for knowing and adding completed Sales. Acceptable in early development cycles if the Store has few responsibilities.

SalesLedger is responsible for knowing and adding completed Sales. Suitable when the design grows and the Store becomes uncohesive.

Logging a completed sale


note that the Sale instance is named 's' so that it can be referenced as a parameter in messages 2 and 2.1

makePayment(cashTendered)

:Register

1: makePayment(cashTendered)

s :Sale

2: addSale(s) by Expert :Store 2.1: add(s)

1.1: create(cashTendered)

:Payment

completedSales: List<Sale>

Sale.getBalance Interaction Diagram


{ bal = pmt.amount - s.total }

bal = getBalance

s :Sale

1: amt = getAmount

pmt: Payment

2: t = getTotal

A more complete DCD reflecting most design decision


Store address : Address name : Text addCompleteSale(...) 1 catalog ... getProductDesc(...) ... description 1 register 1 Register ... endSale() enterItem(...) makeNewSale() makePayment(...) currentSale 1 becomeComplete() makeLineItem(...) makePayment(...) getTotal() Sale isComplete : Boolean time : DateTime lineItems {ordered} 1..* SalesLineItem quantity : Integer getSubtotal() catalog 1 ProductDescription ProductCatalog descriptions description : Text {Map} price : Money 1..* itemID: ItemID

completedSales {ordered}

*
payment 1 ...

Payment amount : Money

Design Class Diagram


Domain Model conceptual perspective ... Sale Register 1 Captures 1 time isComplete : Boolean /total

Register Design Model DCD; software perspective ... endSale() enterItem(...) makePayment(...) 1

Sale time isComplete : Boolean currentSale /total makeLineItem(...)

Determining Visibility
Visibility is the ability of one object to see or have reference to another. For an object A to send message to an object B, B must be visible to A

class Register { ... private ProductCatalog catalog; ... }

enterItem (itemID, quantity)

: Register

: ProductCatalog

desc = getProductDesc( itemID )

public void enterItem( itemID, qty ) { ... desc = catalog.getProductDesc(itemID) ... }

Visibility from Register to ProductCatalog is required

Four types of visibility from A to B


Attribute Visibility: B is an attribute of A Parameter visibility: B is a parameter of a method of A. Locally declared visibility: B is declared as a local object in a method of B Global visibility: B is globally visible

Attribute visibility
Relatively permanent in nature
ProductCatalog is an attribute of Register. Because register needs to send getProductDescription message to catalog ProductCatalog exists as long as Register exists
class Register { ... private ProductCatalog catalog; ... } public void enterItem(itemID, qty) { ... desc = catalog.getProductDesc(itemID) ... }

enterItem (itemID, quantity)

: Register

: ProductCatalog

desc = getProductDesc( itemID )

Parameter Visibility
Relatively temporary visibility
Persists within the scope of the method
enterItem qty) (id, :Register 2: makeLineItem (desc, qty) :Sale

1: desc = getProductDescid) ( 2.1: create(desc, qty) :Product Catalog makeLineItem(ProductDescription desc, int qty) { ... sl = new SalesLineItem (desc ,qty); ... } sl : SalesLineItem

Locally Declared Visibility


enterItem(id, qty) { ... // local visibility via assignment of returning object ProductDescription desc = catalog.getProductDes(id); ... } : Register : ProductCatalog

enterItem (itemID, quantity)

desc = getProductDesc( itemID )

Global Visibility
Least used Least desirable Assign an instance to a global variable

Design Class Diagrams


A design class diagram illustrates the specifications for software classes and interfaces in an application Analysis Class Diagram Design Class Diagram An analysis tool Domain level concepts Operations are absent No navigability A design tool Software classes Operations are present Navigability arrows indicate the direction of visibility Do not show dependency Show dependency relationship relationship

Steps in creating a Design Class Diagram


Identify all the classes participating in the software solution. Draw them in a class diagram Duplicate the attributes from the associated concepts in the analysis class diagram Add methods by analyzing interaction diagrams Add type information to the attributes and the methods Add the association necessary to support attribute visibility Add navigability arrow to indicate the direction of attribute visibility Add dependency relationships to indicate non-attribute visibility

Records-sale-of Product Description Contains 1 1 0..1 Sales LineItem 1 Recordsaccountsfor 1 Used-by Describes 1..*

Ledger

Product Catalog

*
Store Stocks 1 1

*
Item

1 1..* Contained-in 1 Sale Logscompleted

1..*

Houses

1.. * Register

*
Captured-on 0..1 1

NextGen POS partial Domain Model


3 W orks-on 1 Cashier

Paid-by 1 CashPayment

Is-for 1 Customer

Records-sale-of Product Description Contains 1 1 0..1 Sales LineItem quantity 1..* Contained-in 1 Sale dateTime / total 1 Paid-by 1 CashPayment amountTendered 1 Is-for 1 Customer id Logscompleted 1 Recordsaccountsfor 1 Used-by 1..* itemID description price Describes

Ledger

Product Catalog

*
Store Stocks name address 1 1

*
Item

1..*

Houses

1..* Register id 1 3 Works-on 1 Cashier

*
Captured-on 1 0..1

NextGen POS partial Domain Model with some attributes

A more complete DCD reflecting most design decisions


Store address : Address name : Text addCompleteSale(...) 1 catalog ... getProductDesc(...) ... description register 1 Register ... endSale() enterItem(...) makeNewSale() makePayment(...) currentSale 1 becomeComplete() makeLineItem(...) makePayment(...) getTotal() Sale isComplete : Boolean time : DateTime lineItems {ordered} 1..* SalesLineItem quantity : Integer getSubtotal() 1 catalog 1 ProductDescription ProductCatalog descriptions description : Text {Map} price : Money 1..* itemID: ItemID

completedSales {ordered}

*
payment 1 ...

Payment amount : Money

Three tier architecture and packaging


The three tier architecture
Presentation Layer
Windows, reports etc.

Application Layer
Tasks or rules that governs the process

Storage Layer
Persistent storage mechanism

Physical deployment
Client-server environment

Decomposition of Application Layer


Domain Objects (Ex. Sale) Services (Ex. Database interface)

Packages
Group of elements that provide a common service (or a family of related services), with relatively high coupling and collaboration. At a higher level of abstraction the elements are highly cohesive (strongly correlated responsibility)

Architecture Package Diagram


Presentation Presentation

Domain Application Service

Storage

Database

Layers and Partitions of Packages


Domain

Layers

Core Elements

Sales

Product

Service Security

Database Interface

Communic ation

Reporting

partitions

Visibility between the packages


Presentation packages have visibility into many of the domain packages Presentation and domain packages have visibility into only one or few classes in each particular service package No domain or service package have direct visibility into presentation layer (Indirect Communication)

No Direct Visibility to Windows The Model View Separation Pattern


Problem: It is desirable to de-couple domain (model) object from the windows (view) objects, to support increased reuse of domain object and minimize the impact of changes in the user interface on the domain object. What to do? Solution: Define domain (model) classes so that they do not have direct visibility to the windows (view) classes, and the application data and functionality remains with the domain classes, not with window classes.

Motivation for Model-View separation model


To support cohesive model definitions that focus on the domain processes, rather than computer interfaces. To allow separate development of the model and the user interface layers To minimize the impact of requirements changes on the interfaces upon the domain layer To allow new views to be easily connected to an existing domain layer, without affecting the domain layer. To allow multiple simultaneous views on the same model object. To allow the model layer independent of the user interface layer, such as in in a message processing and batch mode system. To allow easy porting of the model layer to another user interface framework.

How do the windows get the data?


Polling or pull from above
It is the responsibility of a window object to ask for the relevant information from the other objects whenever necessary. Most common form But fails when the information gets updated as a result of the state change of the domain object (Ex. stock price, Network monitoring system) Push-from-below model

Publish Subscribe pattern

Indirect Communication in a System Publish-Subscribe Pattern


Problem: A change in state (an event) occurs within a Publisher of the event and the other objects are dependent on or are interested in this event (Subscribed to the event). However, the publisher should not have the direct knowledge of its subscribers. What to do? Solution: Define an event notification system so that the publisher can indirectly notify subscriber. Ex. Mouse Listener, Keyboard listener

Goal: When the total of the sale changes, refresh the display with the new value

Sale total ... setTotal( newTotal ) ...

{ for each PropertyListener pl in propertyListeners pl.onPropertyEvent( this, name, value ); }

{ propertyListeners.add( lis ); }

Sale addPropertyListener( PropertyListener lis ) publishPropertyEvent( name, value ) setTotal( Money newTotal ) ... { total = newTotal; publishPropertyEvent( "sale.total", total ); } javax.swing.JFrame ... setTitle() setVisible() ... propertyListeners

interface PropertyListener onPropertyEvent( source, name, value )

{ if ( name.equals("sale.total") ) saleTextField.setText( value.toString() ); } SaleFrame1 onPropertyEvent( source, name, value ) initialize( Sale sale ) ... { sale.addPropertyListener( this ) ... }

The observer SaleFrame1 subscribes to publisher Sale


sf : SaleFrame1 s : Sale propertyListeners : List<PropertyListener>

initialize( s : Sale ) addPropertyListener( sf ) add( sf )

Sale publishes a property event to all its subscribers


s :Sale setTotal( total ) publishPropertyEvent ( "sale.total", total ) loop onPropertyEvent( s, "sale.total", total ) propertylisteners[ i ] : PropertyListener

Subscriber SaleFrame1 receives notification of a published event


Since this is a polymorphic operation implemented by this class, show a new interaction diagram that starts with this polymorphic version : SaleFrame1 saleTextField : JTextField

onPropertyEvent( source, name, value ) setText( value.toString() )

UML notation: Note this little expression within the parameter. This is legal and consise.

Sale addPropertyListener( PropertyListener lis ) publishPropertyEvent( name, value ) setTotal( Money newTotal ) ... publishes events to observers/listeners/ subscribers registers them when they ask to subscribe

javax.swing.JFrame ... setTitle() setVisible() ...

propertyListeners

interface PropertyListener onPropertyEvent( source, name, value )

SaleFrame1 onPropertyEvent( source, name, value ) initialize( Sale sale ) ...

listens for events observes events subscribes to notification of events

Few More Patterns


More Grasp pattern
Polymorphism Pure Fabrication Indirection

Some GoF patterns


Strategy Faade Command State

Polymorphism
Problem: How to handle alternatives based on type? How to create pluggable software components? Solution: When alternatives or behavior vary by type (class), assign responsibility for the behaviour-using polymorphic operations to the types for which the behaviour varies. Alternatives based on type
Avoiding conditional variation within the program using if-thenelse or case structure

Pluggable s/w component


Client server environment Replacing one server component with other without affecting the client.

How to support third party tax calculators?

interface ITaxCalculatorAdapter getTaxes( Sale ) : List<TaxLineItems>

TaxMasterAdapter

GoodAsGoldTaxPro Adapter

<???>Adapter ... ...

getTaxes( Sale ) : List<TaxLineItems> getTaxes( Sale ) : List<TaxLineItems>

By Polymorphism, multiple tax calculator adapters have their own similar, but varying behavior for adapting to different external tax calculators.These are not the third party
software, but an interface that connects to the third party software

Pure Fabrication
Problem: Who should take the responsibility when you do not want to violate High Cohesion and Low coupling or other goals, but the solution provided by the expert is not appropriate ? Solution: Assign a high cohesive set of responsibilities to an artificial class that does not represent any thing in the problem domain. Ex: Saving sales in a database
Sale class has the necessary information to store itself. But
Sale class has to be coupled with relational database interface (not a domain level concept) Type of relational database may change in the future

Persistent Storage

Insert(Object) Update(Object)

By Pure Fabrication

Indirection
Problem: How to avoid direct coupling? How to decouple objects so that Low Coupling is supported and the reuse potential remains high? Solution: Assign the responsibility to mediate between the other components or services so that they are not directly coupled. The intermediary creates an indirection between the other components or services.

: Sale t = getTotal taxes = getTaxes( s )

:TaxMasterAdapter

TCP socket communication xxx ...

...

actor :TaxMasterSystem

the adapter acts as a level of indirection to external systems

Strategy
Problem: How to design for varying but related, algorithms or policies? How to design for the ability to change these algorithms or policies? Solution: Define each algorithm/policy/ strategy in a separate class, with a common interface.

interface ISalePricingStrategy getTotal( Sale ) : Money

PercentDiscount PricingStrategy percentage : float getTotal( s:Sale ) : Money

AbsoluteDiscount OverThreshold PricingStrategy ... discount : Money threshold : Money getTotal( s:Sale ) : Money ...

??? PricingStrategy

{ return s.getPreDiscountTotal() * percentage }

{ pdt := s.getPreDiscountTotal() if ( pdt < threshold ) return pdt else return pdt - discount }

Faade (A front end object)


A common, unified interface to a disparate set of implementation within a subsystem are required. There may be undesirable coupling to many things in the subsystem, or the implementation of the subsystem may change. What to do? Define a single point of contact to the subsystem- a faade object that wraps the subsystem. This faade object represents a single unified interface and is responsible for collaborating with the subsystem components.

package name may be shown in the tab Domain

+ Sale

+ Register

...

visibility of the package element (to outside the package) can be shown by preceding the element name with a visibility symbol

POSRuleEngine

+ POSRuleEngineFacade instance : RuleEngineFacade getInstance() : RuleEngineFacade isInvalid( SalesLineItem, Sale ) isInvalid( Payment, Sale ) ...

interface - IRule ...

...

- Rule1 ...

- Rule2 ...

State
Problem: An objects behavior is dependent on state. Conditional logic is undesirable because of complexity, scalability or duplication. What to do? Solution:
Create a class for each state that influences the behavior of the sate dependent objects (the context object) Based on the polymorphism, assign methods to each state class to handle the behaviour of the context object When the state dependent message is received by the context object forward it to the state object.

Command
Problem: A variety of requests or commands can be received by an object or system. How to reduce the receivers responsibility in handling the commands, increase the ease with which new commands may be added, and provide a foundation for logging, queuing and undoing commands? Solution: For each command, define a class that represents it and give it responsibility for executing itself.

You might also like