• No results found

Design Principles: Part 1

N/A
N/A
Protected

Academic year: 2021

Share "Design Principles: Part 1"

Copied!
65
0
0

Loading.... (view fulltext now)

Full text

(1)

The Need for Design Principles Refactoring Design Principles References

Design Principles: Part 1

ENGI 5895: Software Design

Andrew Vardy

Faculty of Engineering & Applied Science Memorial University of Newfoundland

January 24, 2018

(2)

The Need for Design Principles Refactoring Design Principles References

Outline

1

The Need for Design Principles

2

Refactoring

3

Design Principles

The Single-Responsibility Principle (SRP)

The Open-Closed Principle (OCP)

(3)

The Need for Design Principles Refactoring Design Principles References

Symptoms of Poor Design

The following are the symptoms of bad software designs, as defined in Ch. 7 of [Martin, 2003]:

Rigidity: The design is hard to change Fragility: The design is easy to break Immobility: The design is hard to reuse

Viscosity: It is hard to do the right thing (i.e. forced into hacks)

Needless Complexity: Overdesign Needless Repetition: Mouse abuse Needless Repetition: (Just kidding) Opacity: Disorganized expression

Also known as design smells.

(4)

The Need for Design Principles Refactoring Design Principles References

Symptoms of Poor Design

The following are the symptoms of bad software designs, as defined in Ch. 7 of [Martin, 2003]:

Rigidity: The design is hard to change

Fragility: The design is easy to break Immobility: The design is hard to reuse

Viscosity: It is hard to do the right thing (i.e. forced into hacks)

Needless Complexity: Overdesign

Needless Repetition: Mouse abuse

Needless Repetition: (Just kidding)

Opacity: Disorganized expression

Also known as design smells.

(5)

The Need for Design Principles Refactoring Design Principles References

Symptoms of Poor Design

The following are the symptoms of bad software designs, as defined in Ch. 7 of [Martin, 2003]:

Rigidity: The design is hard to change Fragility: The design is easy to break

Immobility: The design is hard to reuse

Viscosity: It is hard to do the right thing (i.e. forced into hacks)

Needless Complexity: Overdesign

Needless Repetition: Mouse abuse

Needless Repetition: (Just kidding)

Opacity: Disorganized expression

Also known as design smells.

(6)

The Need for Design Principles Refactoring Design Principles References

Symptoms of Poor Design

The following are the symptoms of bad software designs, as defined in Ch. 7 of [Martin, 2003]:

Rigidity: The design is hard to change Fragility: The design is easy to break Immobility: The design is hard to reuse

Viscosity: It is hard to do the right thing (i.e. forced into hacks)

Needless Complexity: Overdesign

Needless Repetition: Mouse abuse

Needless Repetition: (Just kidding)

Opacity: Disorganized expression

Also known as design smells.

(7)

The Need for Design Principles Refactoring Design Principles References

Symptoms of Poor Design

The following are the symptoms of bad software designs, as defined in Ch. 7 of [Martin, 2003]:

Rigidity: The design is hard to change Fragility: The design is easy to break Immobility: The design is hard to reuse

Viscosity: It is hard to do the right thing (i.e. forced into hacks)

Needless Complexity: Overdesign

Needless Repetition: Mouse abuse

Needless Repetition: (Just kidding)

Opacity: Disorganized expression

Also known as design smells.

(8)

The Need for Design Principles Refactoring Design Principles References

Symptoms of Poor Design

The following are the symptoms of bad software designs, as defined in Ch. 7 of [Martin, 2003]:

Rigidity: The design is hard to change Fragility: The design is easy to break Immobility: The design is hard to reuse

Viscosity: It is hard to do the right thing (i.e. forced into hacks)

Needless Complexity: Overdesign

Needless Repetition: Mouse abuse

Needless Repetition: (Just kidding)

Opacity: Disorganized expression

Also known as design smells.

(9)

The Need for Design Principles Refactoring Design Principles References

Symptoms of Poor Design

The following are the symptoms of bad software designs, as defined in Ch. 7 of [Martin, 2003]:

Rigidity: The design is hard to change Fragility: The design is easy to break Immobility: The design is hard to reuse

Viscosity: It is hard to do the right thing (i.e. forced into hacks)

Needless Complexity: Overdesign Needless Repetition: Mouse abuse

Needless Repetition: (Just kidding)

Opacity: Disorganized expression

Also known as design smells.

(10)

The Need for Design Principles Refactoring Design Principles References

Symptoms of Poor Design

The following are the symptoms of bad software designs, as defined in Ch. 7 of [Martin, 2003]:

Rigidity: The design is hard to change Fragility: The design is easy to break Immobility: The design is hard to reuse

Viscosity: It is hard to do the right thing (i.e. forced into hacks)

Needless Complexity: Overdesign Needless Repetition: Mouse abuse Needless Repetition: (Just kidding)

Opacity: Disorganized expression

Also known as design smells.

(11)

The Need for Design Principles Refactoring Design Principles References

Symptoms of Poor Design

The following are the symptoms of bad software designs, as defined in Ch. 7 of [Martin, 2003]:

Rigidity: The design is hard to change Fragility: The design is easy to break Immobility: The design is hard to reuse

Viscosity: It is hard to do the right thing (i.e. forced into hacks)

Needless Complexity: Overdesign Needless Repetition: Mouse abuse Needless Repetition: (Just kidding) Opacity: Disorganized expression

Also known as design smells.

(12)

The Need for Design Principles Refactoring Design Principles References

Symptoms of Poor Design

The following are the symptoms of bad software designs, as defined in Ch. 7 of [Martin, 2003]:

Rigidity: The design is hard to change Fragility: The design is easy to break Immobility: The design is hard to reuse

Viscosity: It is hard to do the right thing (i.e. forced into hacks)

Needless Complexity: Overdesign Needless Repetition: Mouse abuse Needless Repetition: (Just kidding) Opacity: Disorganized expression

Also known as design smells.

(13)

The Need for Design Principles Refactoring Design Principles References

Symptoms of Poor Design

The following are the symptoms of bad software designs, as defined in Ch. 7 of [Martin, 2003]:

Rigidity: The design is hard to change Fragility: The design is easy to break Immobility: The design is hard to reuse

Viscosity: It is hard to do the right thing (i.e. forced into hacks)

Needless Complexity: Overdesign

Needless Repetition: Mouse abuse

Needless Repetition: (Just kidding)

Opacity: Disorganized expression

Also known as design smells.

(14)

The Need for Design Principles Refactoring Design Principles References

Software Rots

When the requirements change, the system must change—often in ways not anticipated by the initial design. Over time the software begins to acquire design smells... The software rots!

The design should be kept as clean, simple, and as expressive as possible

Never say, ”we’ll fix that later” ...because you won’t!

When a requirement changes, the design should be updated to

be resilient to that kind of change in the future

(15)

The Need for Design Principles Refactoring Design Principles References

Software Rots

When the requirements change, the system must change—often in ways not anticipated by the initial design. Over time the software begins to acquire design smells... The software rots!

The design should be kept as clean, simple, and as expressive as possible

Never say, ”we’ll fix that later” ...because you won’t!

When a requirement changes, the design should be updated to

be resilient to that kind of change in the future

(16)

The Need for Design Principles Refactoring Design Principles References

Software Rots

When the requirements change, the system must change—often in ways not anticipated by the initial design. Over time the software begins to acquire design smells... The software rots!

The design should be kept as clean, simple, and as expressive as possible

Never say, ”we’ll fix that later”

...because you won’t!

When a requirement changes, the design should be updated to

be resilient to that kind of change in the future

(17)

The Need for Design Principles Refactoring Design Principles References

Software Rots

When the requirements change, the system must change—often in ways not anticipated by the initial design. Over time the software begins to acquire design smells... The software rots!

The design should be kept as clean, simple, and as expressive as possible

Never say, ”we’ll fix that later”

...because you won’t!

When a requirement changes, the design should be updated to

be resilient to that kind of change in the future

(18)

The Need for Design Principles Refactoring Design Principles References

Software Rots

When the requirements change, the system must change—often in ways not anticipated by the initial design. Over time the software begins to acquire design smells... The software rots!

The design should be kept as clean, simple, and as expressive as possible

Never say, ”we’ll fix that later”

...because you won’t!

When a requirement changes, the design should be updated to

be resilient to that kind of change in the future

(19)

The Need for Design Principles Refactoring Design Principles References

Refactoring

How do we modify our designs and our code to prevent rot.

Refactoring...

Refactoring ”...the process of changing a software system in such a way that it does not alter the external behaviour of the code yet improves its internal structure” [Fowler, 1999]

You can refactor code:

e.g. Read ch. 5 of [Martin, 2003]

You can refactor your design:

We will see many examples

(20)

The Need for Design Principles Refactoring Design Principles References

Refactoring

How do we modify our designs and our code to prevent rot.

Refactoring...

Refactoring ”...the process of changing a software system in such a way that it does not alter the external behaviour of the code yet improves its internal structure” [Fowler, 1999]

You can refactor code:

e.g. Read ch. 5 of [Martin, 2003]

You can refactor your design:

We will see many examples

(21)

The Need for Design Principles Refactoring Design Principles References

Refactoring

How do we modify our designs and our code to prevent rot.

Refactoring...

Refactoring ”...the process of changing a software system in such a way that it does not alter the external behaviour of the code yet improves its internal structure” [Fowler, 1999]

You can refactor code:

e.g. Read ch. 5 of [Martin, 2003]

You can refactor your design:

We will see many examples

(22)

The Need for Design Principles Refactoring Design Principles References

Refactoring

How do we modify our designs and our code to prevent rot.

Refactoring...

Refactoring ”...the process of changing a software system in such a way that it does not alter the external behaviour of the code yet improves its internal structure” [Fowler, 1999]

You can refactor code:

e.g. Read ch. 5 of [Martin, 2003] You can refactor your design:

We will see many examples

(23)

The Need for Design Principles Refactoring Design Principles References

Refactoring

How do we modify our designs and our code to prevent rot.

Refactoring...

Refactoring ”...the process of changing a software system in such a way that it does not alter the external behaviour of the code yet improves its internal structure” [Fowler, 1999]

You can refactor code:

e.g. Read ch. 5 of [Martin, 2003]

You can refactor your design:

We will see many examples

(24)

The Need for Design Principles Refactoring Design Principles References

Refactoring

How do we modify our designs and our code to prevent rot.

Refactoring...

Refactoring ”...the process of changing a software system in such a way that it does not alter the external behaviour of the code yet improves its internal structure” [Fowler, 1999]

You can refactor code:

e.g. Read ch. 5 of [Martin, 2003]

You can refactor your design:

We will see many examples

(25)

The Need for Design Principles Refactoring Design Principles References

Refactoring

How do we modify our designs and our code to prevent rot.

Refactoring...

Refactoring ”...the process of changing a software system in such a way that it does not alter the external behaviour of the code yet improves its internal structure” [Fowler, 1999]

You can refactor code:

e.g. Read ch. 5 of [Martin, 2003]

You can refactor your design:

We will see many examples

(26)

The Need for Design Principles Refactoring Design Principles References

The Single-Responsibility Principle (SRP)

A class should have only one responsibility.

OR

A class should have only one reason to change.

A class with several responsibilities creates unnecessary couplings

between those responsibilities.

(27)

The Need for Design Principles Refactoring Design Principles References

The Single-Responsibility Principle (SRP)

A class should have only one responsibility.

OR

A class should have only one reason to change.

A class with several responsibilities creates unnecessary couplings

between those responsibilities.

(28)

The Need for Design Principles Refactoring Design Principles References

The Single-Responsibility Principle (SRP)

A class should have only one responsibility.

OR

A class should have only one reason to change.

A class with several responsibilities creates unnecessary couplings

between those responsibilities.

(29)

The Need for Design Principles Refactoring Design Principles References

The Single-Responsibility Principle (SRP)

A class should have only one responsibility.

OR

A class should have only one reason to change.

A class with several responsibilities creates unnecessary couplings

between those responsibilities.

(30)

The Need for Design Principles Refactoring Design Principles References

The Single-Responsibility Principle (SRP)

A class should have only one responsibility.

OR

A class should have only one reason to change.

A class with several responsibilities creates unnecessary couplings

between those responsibilities.

(31)

e.g. Rectangle Class

The Geometry Application is concerned with the mathematics of geometric shapes

The Graphical Application may also involve some geometry, but it also needs to draw geometric shapes

The Rectangle class has two responsibilities:

Provide a mathematical model of a rectangle

Render a rectangle

(32)

e.g. Rectangle Class

The Geometry Application is concerned with the mathematics of geometric shapes

The Graphical Application may also involve some geometry, but it also needs to draw geometric shapes

The Rectangle class has two responsibilities:

Provide a mathematical model of a rectangle

Render a rectangle

(33)

e.g. Rectangle Class

The Geometry Application is concerned with the mathematics of geometric shapes

The Graphical Application may also involve some geometry, but it also needs to draw geometric shapes

The Rectangle class has two responsibilities:

Provide a mathematical model of a rectangle

Render a rectangle

(34)

e.g. Rectangle Class

The Geometry Application is concerned with the mathematics of geometric shapes

The Graphical Application may also involve some geometry, but it also needs to draw geometric shapes

The Rectangle class has two responsibilities:

Provide a mathematical model of a rectangle

Render a rectangle

(35)

e.g. Rectangle Class

The Geometry Application is concerned with the mathematics of geometric shapes

The Graphical Application may also involve some geometry, but it also needs to draw geometric shapes

The Rectangle class has two responsibilities:

Provide a mathematical model of a rectangle

Render a rectangle

(36)

e.g. Rectangle Class

The Geometry Application is concerned with the mathematics of geometric shapes

The Graphical Application may also involve some geometry, but it also needs to draw geometric shapes

The Rectangle class has two responsibilities:

Provide a mathematical model of a rectangle

Render a rectangle

(37)

[Figure repeated]

Problems created:

Inclusion: The GUI must be included in the Geometry

Application (C++: linked into executable, Java: GUI.class file included in JAR file)

A change required for one application may affect the other

(e.g. adding a colour attribute)

(38)

[Figure repeated]

Problems created:

Inclusion: The GUI must be included in the Geometry

Application (C++: linked into executable, Java: GUI.class file included in JAR file)

A change required for one application may affect the other

(e.g. adding a colour attribute)

(39)

[Figure repeated]

Problems created:

Inclusion: The GUI must be included in the Geometry

Application (C++: linked into executable, Java: GUI.class file included in JAR file)

A change required for one application may affect the other

(e.g. adding a colour attribute)

(40)

[Figure repeated]

Problems created:

Inclusion: The GUI must be included in the Geometry

Application (C++: linked into executable, Java: GUI.class file included in JAR file)

A change required for one application may affect the other

(e.g. adding a colour attribute)

(41)

Solution:

Separate the two responsibilities (math rep. + drawing) into

two separate classes

(42)

Solution:

Separate the two responsibilities (math rep. + drawing) into

two separate classes

(43)

Solution:

Separate the two responsibilities (math rep. + drawing) into

two separate classes

(44)

e.g. Modem Interface

interface Modem

{

void dial

(

String pno

) ;

void hangup

( ) ;

void send

(

char c

) ;

char recv

( ) ; }

Multiple responsibilities? You could say there are two:

Connection management (dial, hangup)

Data transfer (send, recv)

(45)

e.g. Modem Interface

interface Modem

{

void dial

(

String pno

) ;

void hangup

( ) ;

void send

(

char c

) ;

char recv

( ) ; }

Multiple responsibilities? You could say there are two:

Connection management (dial, hangup)

Data transfer (send, recv)

(46)

e.g. Modem Interface

interface Modem

{

void dial

(

String pno

) ;

void hangup

( ) ;

void send

(

char c

) ;

char recv

( ) ; }

Multiple responsibilities? You could say there are two:

Connection management (dial, hangup)

Data transfer (send, recv)

(47)

e.g. Modem Interface

interface Modem

{

void dial

(

String pno

) ;

void hangup

( ) ;

void send

(

char c

) ;

char recv

( ) ; }

Multiple responsibilities? You could say there are two:

Connection management (dial, hangup)

Data transfer (send, recv)

(48)

If connection management and data transfer are considered

separate responsibilities then we can provide the following solution:

However, what if connection management and data transfer always

change together? Then Modem has only one reason for change and

can be left as is. To modify Modem in this case would smell of

needless complexity.

(49)

If connection management and data transfer are considered

separate responsibilities then we can provide the following solution:

However, what if connection management and data transfer always

change together? Then Modem has only one reason for change and

can be left as is. To modify Modem in this case would smell of

needless complexity.

(50)

If connection management and data transfer are considered

separate responsibilities then we can provide the following solution:

However, what if connection management and data transfer always

change together? Then Modem has only one reason for change and

can be left as is. To modify Modem in this case would smell of

needless complexity.

(51)

[Figure repeated]

Consider our solution again. Modem Implementation has two responsibilities! Isn’t this bad? Yes but...

This may be unavoidable due to h/w or OS constraints

Even if Modem Implementation changes, other classes in the

system should remain unaffected

(52)

[Figure repeated]

Consider our solution again. Modem Implementation has two responsibilities! Isn’t this bad? Yes but...

This may be unavoidable due to h/w or OS constraints

Even if Modem Implementation changes, other classes in the

system should remain unaffected

(53)

[Figure repeated]

Consider our solution again. Modem Implementation has two responsibilities! Isn’t this bad? Yes but...

This may be unavoidable due to h/w or OS constraints

Even if Modem Implementation changes, other classes in the

system should remain unaffected

(54)

The Need for Design Principles Refactoring Design Principles References

The Open-Closed Principle (OCP)

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

OR

To change behaviour, add new code rather than changing existing code.

How? Abstraction.

(55)

The Need for Design Principles Refactoring Design Principles References

The Open-Closed Principle (OCP)

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

OR

To change behaviour, add new code rather than changing existing code.

How? Abstraction.

(56)

The Need for Design Principles Refactoring Design Principles References

The Open-Closed Principle (OCP)

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

OR

To change behaviour, add new code rather than changing existing code.

How? Abstraction.

(57)

e.g. Client Server

With regards to the Client, the following design does not conform to the OCP.

If we want the Client to use a different Server, we must change the

Client. However, the following design resolves this problem:

(58)

e.g. Client Server

With regards to the Client, the following design does not conform to the OCP.

If we want the Client to use a different Server, we must change the

Client. However, the following design resolves this problem:

(59)

e.g. Client Server

With regards to the Client, the following design does not conform to the OCP.

If we want the Client to use a different Server, we must change the

Client. However, the following design resolves this problem:

(60)

The DrawShape function violates the OCP:

class Shape {

enum ShapeType {SQUARE, CIRCLE} itsType; Shape(ShapeType t) : itsType(t) {} } ;

class Circle : public Shape { Circle( ) : Shape(CIRCLE) { } ; void Draw( ) ;

// . . . } ;

class Square : public Shape { Square( ) : Shape(SQUARE) { } ; void Draw( ) ;

// . . . } ;

void DrawShape(const Shape& s) { if (s.itsType == Shape: :SQUARE)

static_cast<const Square&>(s) .Draw( ) ; else if (s.itsType == Shape: :CIRCLE)

static_cast<const Circle&>(s) .Draw( ) ; }

New derivatives of Shape require changes to DrawShape.

(61)

The DrawShape function violates the OCP:

class Shape {

enum ShapeType {SQUARE, CIRCLE} itsType; Shape(ShapeType t) : itsType(t) {}

} ;

class Circle : public Shape { Circle( ) : Shape(CIRCLE) { } ; void Draw( ) ;

// . . . } ;

class Square : public Shape { Square( ) : Shape(SQUARE) { } ; void Draw( ) ;

// . . . } ;

void DrawShape(const Shape& s) { if (s.itsType == Shape: :SQUARE)

static_cast<const Square&>(s) .Draw( ) ; else if (s.itsType == Shape: :CIRCLE)

static_cast<const Circle&>(s) .Draw( ) ; }

New derivatives of Shape require changes to DrawShape.

(62)

The DrawShape function violates the OCP:

class Shape {

enum ShapeType {SQUARE, CIRCLE} itsType; Shape(ShapeType t) : itsType(t) {}

} ;

class Circle : public Shape { Circle( ) : Shape(CIRCLE) { } ; void Draw( ) ;

// . . . } ;

class Square : public Shape { Square( ) : Shape(SQUARE) { } ; void Draw( ) ;

// . . . } ;

void DrawShape(const Shape& s) { if (s.itsType == Shape: :SQUARE)

static_cast<const Square&>(s) .Draw( ) ; else if (s.itsType == Shape: :CIRCLE)

static_cast<const Circle&>(s) .Draw( ) ; }

New derivatives of Shape require changes to DrawShape.

(63)

The use of virtual methods solves this problem:

class Shape

{

public

:

virtual void Draw

( )

const

= 0 ; } ;

class Square

:

public Shape

{

public

:

virtual void Draw

( )

const

; // . . .

} ;

class Circle

:

public Shape

{

public

:

virtual void Draw

( )

const

; // . . .

} ;

void DrawShape

(

const Shape& s

) {

s

.

Draw

( ) ;

}

(64)

The use of virtual methods solves this problem:

class Shape

{

public

:

virtual void Draw

( )

const

= 0 ; } ;

class Square

:

public Shape

{

public

:

virtual void Draw

( )

const

; // . . .

} ;

class Circle

:

public Shape

{

public

:

virtual void Draw

( )

const

; // . . .

} ;

void DrawShape

(

const Shape& s

) {

s

.

Draw

( ) ;

}

(65)

The Need for Design Principles Refactoring Design Principles References

References

Martin Fowler. Refactoring: Improving the Design of Existing Code.

Addison-Wesley, 1999.

Robert C. Martin. Agile Software Development: Principles,

Patterns, and Practices. Prentice Hall, 2003.

References

Related documents

Although a few authors have explored the influence of work-life balance on women in the context of several countries (Das 2016; Lakshmi and Gopinath 2013; Meenakshi, Subrahmanyam

necessary to gauge the mortality profile of the lives associated with life settlement pools include the insured’s: age last birthday; gender; smoking status; documented

Distribution depots refer to selected depots that are responsible for ordering the HIV PEP kits directly from the vendor and distributing them to other depots within their

REPORT ON PROPOSED NEW INTERIOR DESIGN SCHEME OF LONSDALE RETAIL STORE FOR TNT KICKBOXING AT LOT 322-324 LEVEL 3, RAMLEE MALL,.. SURIA KLCC,

The annual composite dispersion presented is an equal-weighted standard deviation calculated using the annual gross returns of the accounts in the composite for the entire year..

According to Table 1, the financial health of Canadian firms in bankruptcy is critical; the mean and median liabilities to assets ratio are respectively equal to 72.2 and 8.1 for

Lastly, significant bleaching events are more likely to occur in the Coral Triangle during a La Nin˜a, and not during El Nin˜o, with the northern areas more likely affected during

implemented on 112-calls from mobile phones, hoping to reduce the 640 000 ”silent” calls (effect: reduced the number of silent calls with 13,3% in the four test counties last