Sei sulla pagina 1di 23

LECTURE 6: Object Oriented Design

Ivan Marsic
Rutgers University
Topics
• Assigning Responsibilities to Objects
• Design Principles
• Expert Doer
• High Cohesion
• Low Coupling

• Business Policies
• Class Diagram

2
System Sequence Diagrams
We already worked with interaction diagrams: System Sequence Diagrams

: System
User Timer
«initiating actor» «offstage actor»
select function(“unlock")

prompt for the key

enter key
verify key

signal: valid key, lock open


open the lock,
turn on the light

start ("duration“)

System Sequence Diagrams considered interactions between the actors


3
Design: Object Interactions
Design
Sequence Diagram

System Sequence Diagram

Controller : Checker : KeyStorage : LockCtrl

User
«initiating actor»
ystem
: System
Timer
«offstage actor»
checkKey()
sk := getNext()
select function(“unlock")

prompt for the key


alt val != null setOpen(true)
enter key
verify key

signal: valid key, lock open


open the lock,
[else] val == null : setLit(true)
turn on the light

start ("duration“)

• System Sequence Diagrams considered interactions between the actors


• Object Sequence Diagrams consider interactions between the objects 4
Metaphor for Software Design:
“Connecting the Dots”

:InterfacePage :SearchRequest :Controller :PageMaker :DatabaseConn :Archiver :Notifier :InvestigRequest


Resident Database Landlord

We start with objects/concepts from the Domain


Model and modify or introduce new objects, as
needed to make the system function work.
5
Types of Object Responsibilities
• Knowing responsibility: Memorizing data or
references, such as data values, data
collections, or references to other objects,
represented as a property
• Doing responsibility: Performing computations,
such as data processing, control of physical
devices, etc., represented as a method
• Communicating responsibility: Communicating
with other objects, represented as message
sending (method invocation)

6
Design: Assigning
Responsibilities

? ? : DatabaseConn : PageMaker : Controller : Checker : DeviceCtrl

checkKey()
accessList := retrieve(params : string)

R1.
interfacePage := activate( "lock" )
render(accessList : string) ?
R2.

(a) (b)

7
Characteristics of Good Designs
• Short communication chains between the
objects

• Balanced workload across the objects


method_1() method_1()
method_2()

method_N()

• Low degree of connectivity (associations)


among the objects

8
Design Principles
• Expert Doer Principle: that who knows should
do the task

• High Cohesion Principle: do not take on too


many computation responsibilities

• Low Coupling Principle: do not take on too many


communication responsibilities

There are many more …


9
Design: Assigning
Responsibilities
: Controller : Checker : DevCtrl : Controller : Checker : DevCtrl

checkKey() ok := checkKey()

setOpen(true) setOpen(true)
?

(a) (b)

• Although the Checker is the first to acquire the information about the key validity,
we decide to assign the responsibility to notify the LockCtrl to the Controller.
• This is because the Controller would need to know this information anyway—to
inform the user about the outcome of the key validity checking.
• In this way we maintain the Checker focused on its specialty and avoid assigning
too many responsibilities to it.
10
Cohesion

Low cohesion

High cohesion

11
Responsibility-Driven Design
1. Identify the responsibilities
• domain modeling provides a starting point
• some will be missed at first and identified in subsequent iterations

2. For each responsibility, identify the alternative


assignments
– if the choice appears to be unique then move to the next
responsibility

3. Consider the merits and tradeoffs of each alternative


by applying the design principles
– select what you consider the “optimal” choice

4. Document the process by which you arrived to each


responsibility assignment
12
UC-4: View Access Log

«html»
interfacePage : : Controller : PageMaker : DatabaseConnection
Resident Database

specify get( queryRequest : string )


query accessList := retrieve(params : string)
request retrieve records

result

interfacePage := render(accessList : string)

alt accessList != NULL


page :=
renderList()

[else] page :=
warning()

result «post page»


displayed

13
Example …
Communicating responsibilities identified for the system function “enter key”:

Responsibility Description
Send message to Key Checker to validate the key entered by the user.

Send message to DeviceCtrl to disarm the lock device.

Send message to DeviceCtrl to switch the light bulb on.

Send message to PhotoObserver to report whether daylight is sensed.

Send message to DeviceCtrl to sound the alarm bell.

14
Unlocking Sequence Diagram

: Controller : Checker : KeyStorage : LockCtrl : LightCtrl : Logger

checkKey()
sk := getNext()

alt val != null setOpen(true)

[else] val == null : setLit(true)

logTransaction(val)

sk = stored key; the process either terminates by matching a stored key or


exhausting the key store.
Key is a dynamic object, unlike others which are static contains keycode, name,
other forms of ID, timestamp, door ID, … -- disposed of after checking 15
Unlock Use Case
: Controller k : Key : Checker : KeyStorage : DeviceCtrl : PhotoObsrv : Logger

enterKey()
«create»

loop [for all stored keys]


val := checkKey( k )
sk := getNext()

compare(k, sk)

logTransaction( k, val )
«destroy»

alt val == true activate( "lock" )

dl := isDaylight()

opt dl == false activate( "bulb" )

[else] numOfAttempts++

alt numOfAttempts == maxNumOfAttempts


denyMoreAttempts()

activate( "alarm" )

[else]

prompt: "try again"


16
Unlock Seq. Diag. Variation 1

: Controller k : Key : Checker : KeyStorage : LockCtrl

k := create()

checkKey(k) loop
sk := getNext()

setValid(ok)

controlLock(k)
ok := isValid()

opt ok == true

setOpen(true)

To avoid an impression that the above design is the only one possible!!

Sets a boolean attribute of the Key object: ok = true/false;


Business logic (IF-THEN rule) relocated from Controller to LockCtrl
17
Unlock Seq. Diag. Variations 2&3

: LightCtrl : PhotoSObs : LightCtrl : PhotoSObs

controlLight() checkIfDaylightAndIfNotThenSetLit()
dl := isDaylight() dl := isDaylight()

opt dl == false The caller opt dl == false


could be
Controller or
setLit(true) KeyChecker setLit(true)

Depends on which solution you consider more elegant;


It is helpful that checkIfDaylightAndIfNotThenSetLit() is named informatively (reveals the
intention), but the knowledge encoded in the name of the method is imparted onto the caller.
18
Summary of Design Variations
c
: Controller k : Key : Checker : KeyStorage : DeviceCtrl : PhotoObsrv : Logger
: DeviceCtrl : PhotoSObs
enterKey()
k := create()

loop [for all stored keys]


val := checkKey(k)
sk := getNext()

compare()
activate( "light" )
logTransaction(k, val) dl := isDaylight()
«destroy»

alt val == true activate(“lock”)

opt dl == false
dl := isDaylight()

a opt dl == false activate(“bulb”) setLit(true)

: Controller k : Key [else]


: Checker
numOfTrials++ : KeyStorage : DeviceCtrl
prompt:
"try again"
k := create()
opt numOfTrials == maxNumOfTrials activate(“alarm”)

loop
b
checkKey(k) : DeviceCtrl : PhotoSObs
sk := getNext()

setValid(ok)
checkIfDaylightAndIfNotThenSetLit()
controlLock(k) dl := isDaylight()

ok := isValid()
The caller opt dl == false
opt ok == true
could be
Controller or
setOpen(true) Checker setLit(true)
19
Business Policies

IF key  ValidKeys THEN disarm lock and turn lights on


ELSE
increment failed-attempts-counter
IF failed-attempts-counter equals maximum number allowed
THEN block further attempts and raise alarm

Should be moved into a separate object:


• Make them explicit part of the model
• Confine the future changes in business policies
20
Class Diagram
Base Class
Container

PhotoSObsrv Key KeyStorage


1..* 1
– code_ : string
+ isDaylight() : boolean – timestamp_ : long + getNext() : Key
– doorLocation_ : string
1 sensor validKeys 1

Controller
# numOfAttemps_ : long
# maxNumOfAttempts_ : long
+ enterKey(k : Key)
– denyMoreAttempts() KeyChecker
1

checker + checkKey(k : Key) : boolean


1 devCtrl – compare(k : Key, sk : Key) : boolean

DeviceCtrl
1 logger
# devStatuses_ : Vector
Logger + activate(dev : string) : boolean
+ deactivate(dev :string) : boolean
+ logTransaction(k : Key) + getStatus(dev : string) : Object

21
Traceability Matrix (3)
Mapping: Domain model to Class diagram
Software Classes

«html» interfacePage

DatabaseConnection
SearchRequest
Controller-SS1

Controller-SS2
PhotoSObsrv
KeyChecker
KeyStorage

PageMaker
DeviceCtrl

Logger
Key
Domain Concepts

Controller-SS1 X
StatusDisplay
Key X
KeyStorage X
KeyChecker X
HouseholdDeviceOperator X
IlluminationDetector X
Controller-SS2 X
SearchRequest X
InterfacePage X
PageMaker X
Archiver
DatabaseConnection X
Notifier
InvestigationRequest
22
Types of Object Communication

SS11
AA BB

SS22
AA BB PP

SSNN
(a) (b) (c)

23

Potrebbero piacerti anche