+ All Categories
Home > Documents > 1 OO Design Novosoft, 2001 by V. Mukhortov. 2 OO Design Goals Flexibility Changes must be localized...

1 OO Design Novosoft, 2001 by V. Mukhortov. 2 OO Design Goals Flexibility Changes must be localized...

Date post: 29-Dec-2015
Category:
Upload: derek-reed
View: 213 times
Download: 0 times
Share this document with a friend
42
1 OO Design Novosoft, 2001 by V. Mukhortov
Transcript

1

OO Design

Novosoft, 2001

by V. Mukhortov

2

OO Design Goals

FlexibilityChanges must be localized

MaintainabilityModules requiring changes can be easily identified and changes can be made at their place and cost

ReusabilityModules should be able to be used in other contexts

3

OO Designer Activities

Class design

Package design

Describing the design patterns

4

Class design principles

ORR One Responsibility Rule LSP Liskov Substitution Principle LoD Law of Demeter OCP Open-Closed Principle ISP Interface Segregation Principle

5

ORR - One Responsibility Rule

A class has a single responsibility:

it does it all, it does it well, it does it only

- R. Martin

6

LSP – Liskov Substitution Principle

Functions that use pointers or references to base classes must be able to use objects of the derived classes without knowing it.

- R.Martin, 1996

Original formula: If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T the behavior of P is unchanged when o1 is substituted by o2 then S is a subtype of T.

- Barbara Liskov, 1988

7

LSP violation: Rectangle & Square

Problem:Square s = new Square(5);s.setHeight(6); // s is not consistent

class Rectangle{ private int h; private int w; public Rectangle( int w, int h ) { this.h = h; this.w = w; } public void setHeight( int h ) { this.h = h; } public int getHeight() { return h; } }class Square extends Rectangle{ public Square( int s ) { super( s, s ); }}

Rectangle

Rectangle(w : int, h : int)setHeight(h : int) : voidgetHeight() : intsetWidth(w : int) : voidgetWidth() : int

Square

Square(s : int)

8

class Square extends Rectangle{ public Square( int s ) { super( s, s ); } public void setSize( int s ) { super.setHeight(s); super.setWidth(s); } public void setHeight( int h ) { setSize(h); } public void setWidth( int w ) { setSize(w); }}

Rectangle

Rectangle(w : int, h : int)setHeight(h : int) : voidgetHeight() : intsetWidth(w : int) : voidgetWidth() : int

Square

Square(s : int)setSize(s : int) : voidsetHeight(h : int) : voidsetWidth(w : int) : void

Problem:void f( Rectangle r ) throws Exception { r.setHeight(4); r.setWidth(5); if( r.getHight() * r.getWidth() != 20 ) throw new Exception( “Bug!” );}

9

LSP: The real problem

• ?

• Square object is not a Rectangle object!

• Why?

• Because of behavior of a Square is not consistent with the behavior of a Rectangle!

• and …

• it is behavior that software is really all about! IsA is a behavioral relationship.

10

LoD – Law of Demeter

Original formula: Only talk to your immediate friends. - Ian Holland, 1987

immediate friends of method f :• methods of class of f and other argument classes of f • methods of immediate part classes of class of f • methods of classes of objects that are created in f .

A method should have limited knowledge of an object model.

- D. Rumbaugh

11

Booch about The LoD

“The basic effect of applying this Law is the creation of loosely coupled classes, whose implementation secrets are encapsulated. Such classes are fairly unencumbered, meaning that to understand the meaning of one class, you need not understand the details of many other classes.”

12

LoD violation

Problem: public void getTimeOfBirth() {

long time = p.getDateOfBirth().getTime();

}

Do not reveal a class secret!

Application

getTimeOfBirth()

Person

getDateOfBirth() : java.util.Date

java.util.Date

getTime()

-dateOfBirth

13

LoD-compliant design

A

foo()

C

m()

B

call_foo()

-a

-b

Solution: void m() { this.b.call_foo(); } // hide the class secret!

14

OCP – Open-Closed Principle

Software entities (classes, modules, functions, etc) should be open for extension, but closed for modification.

- B. Meyer, 1988

15

OCP violation: Shapes

Shape

$ SQUARE : int = 1$ CIRCLE : int = 2

getType()

Circle

getType()

Square

getType()

void drawShapes( Shape[] shapes ) { for( int i = 0; i < shapes.length; ++i ) { if( shape[i].getType == Shape.SQUARE ) { drawSquare( (Square)shape[i] ); } else drawCircle( (Circle)shape[i] ); }}

The problem:You can't add a new shape without changing drawShapes() code.

16

OCP compliant solution

Circle

draw()

Square

draw()

Shape

draw(device : DrawDevice) : void

<<Interface>>DrawDevice

<<Interface>>

Triangle

draw()

void drawShapes( Shape[] shapes ) { for( int i=0; i < shapes.length; ++i ) { shape[i].draw( device ); }}

17

ISP – Interface Segregation Principle

Clients should not be forced to depend upon services they do not use.

- R.Martin, 1996

Hints: Avoid fat interfaces Separate clients mean separate interfaces

Violation cost: lack of flexibility

18

ISP violation: Security Door

Door

lock() : voidunlock() : voidis_open() : bool

Timer

register(timeout : int, client : TimerClient) : void

TimerClient

timeout()

<<Interface>>

Door has to sound an alarm if it is open for too long.Problem: Timeout method has to be public. But…there are Door clients that do NOT use timeout method and don’t have to. This approach leads to mistakes.

19

ISP-compliant Security Door

TimerClient

timeout()

<<Interface>>

Door

lock() : voidunlock() : voidis_open() : bool

TimedDoor

Timer

register(timeout : int, client : TimerClient) : void

Door clients still can use TimedDoor via Door interface Door clients will not be affected by changes made in Timer, TimerClient and TimedDoor

20

ISP violation: ATM Transactions

Adding new transactions causes all other transactions to recompile If any Transaction requires a change to UI, all of the other will be forced to recompile

Transaction

commit()rollback()

<<Interface>>

Deposit

Withdraw

Transfer

UI

getDepositAmount()getWithdrawAmount()getTransferAmount()

21

ISP-compliant solution

Transaction<<Interface>>

Withdraw

WithdrawUI<<Interface>>

Transfer

TransferUI<<Interface>>

Deposit

DepositUI<<Interface>>

UI

getDepositAmount()getWithdrawAmount()getTransferAmount()

22

Dependencies

MDP Minimal Dependencies Principle DIP Dependency Inversion Principle ADP Acyclic Dependencies Principle

23

DIP – Dependency Inversion Principle

High level modules should not depend upon low-level ones. Both should depend upon abstractions.

Abstractions should not depend upon implementation details.Details should depend upon abstractions.

- R.Martin, 1996

24

DIP violation: Copier

Keyboard

readChar()

Copy

copy()

Printer

printChar()

What if we need to support another kind of printer ?

25

DIP-compliant solution

Now we can easily add new writers and readers

Keyboard

readChar()

Printer

printChar()

Reader

readChar()

<<Interface>>Copy

copy()Writer

printChar()

<<Interface>>

26

ADP – Acyclic Dependencies Principle

The dependency structure between entities (classes, packages, functions) must be a Directed Acyclic Graph (DAG).

- R.Martin, 1996

Two entities having to know about each other can not be used separately. They work like a monolith and there is no benefit in separating them.

Increases maintainability

27

Example: cyclic dependenciesApplication

MyTasks TaskWindow

Task

Windows

MessageWindow

MyDialogs

Due to the dependency from MyDialogs to Application, MyTasks package depends upon the entire system.

28

Package design principles

CCP - Common Closure Principle REP - Reuse-Release Equivalence Principle CRP - Common Reuse Principle SDP - Stable Dependencies Principle SAP - Stable Abstractions Principle

29

CCP – Common Closure Principle

Classes within the package should be affected by the same kind of changes. Either all open to the kind of change or all closed to the kind of change.

- R.Martin, 1996

Produces packages where changes are very localized, and, therefore, number of releases is minimized.

30

REP - Reuse/Release Equivalence Principle

The unit of reuse is the unit of release. The unit is what UML refers to as a package.

- R.Martin, 1996

Classes should be grouped into packages according to how they will be reused To be effectively reused, packages must be given a release number

Makes updates convinient for reusers

31

CRP – Common Reuse Principle

The classes in a package are to be reused together. Reusers should depend upon the entire package, not just a part of it.

- R.Martin, 1996

ISP, scaled to packages

Reduces maintenance cost, increases reusability

My PackageAnother Package

class I'm NOT using

class i'm using

32

CRP violation: remote service

Problem: Every time the new version of Service is released, clients of ServiceAgent must expect that their code won’t work, even if changes do not affect ServiceAgent.

Service

Service

ServiceServer(from Service)

ServiceImpl(from Service)

Application

Main

ServiceAgent(from Service)

ServiceException(from Service)

33

CRP compliant design

Clients of ServiceAgent depend only upon things they really use.Benefit: Application can easily switch from local to remote service implementation.

serviceagent

server

local

ServiceServiceAgent

Main ServiceImpl

ServiceServer

application

34

CRP compliant design

serviceagent

server

localapplication

Service

Main

ServiceServer

ExceptionServiceAgent

CallbackServiceImpl

Clients of ServiceAgent depend only upon things they really use.Benefit: Changes in local and server packages do not affect application

35

SDP - Stable Dependencies Principle

A package should only depend upon packages that are more stable than itself. Stability is a measure of difficulty in changing a package.

- R.Martin, 1996

What makes a package hard to change?

Increases maintainability

36

Instability Definition

Instability of a package

I = Ce / ( Ca + Ce )where

Ce = efferent couplings (number of classes inside the package that depend upon classes outside the package )

Ca = afferent couplings (number of classes outside the package that depend upon classes within the package)

37

SAP – Stable Abstractions Principle

The abstractness of the package should be proportional to its stability.

- R.Martin, 1996

If all packages are maximally stable, the system would be unchangable . Therefore, some packages must be instable.

Increases maintainability

38

Abstractness Definition

Abstractness of a package

A = Na / Nwhere

Na = number of abstract classesN = total number of classes

39

Main sequence

Main Sequence – an instability versus abstractness graph Packages along the line from (0,1) to (1,0) have a good balance

Distance from the main sequence

D = | A + I – 1 |

Given this metric, a design can be analyzed for its overall conformance to the main sequence.

- R.Martin, 1994

40

Main sequence

I

A

1

10

USELESS

AREA

CONCRETECLASSES

41

Example: server

What happens if ResultSet is not an interface?

AbstractServer

MyServer

Client

Server ResultSet

Code

SomeServer SomeResultSet

I=0 A=1 D=0

I = 1/1 = 1A= 0D= 0

I=2/3 A=0 D=1/3

42

Example: server

AbstractServer

MyServer

ClientServer

ResultSet

Code

SomeServer

I=1 A=0 D=0

I=0 A=1/2 D=1/2

I=1/2 A=0 D=1/2

This change affects both MyServer and AbstractServer balance


Recommended