CS计算机代考程序代写 flex week 03

week 03

&203�����
�’HVLJQ�3ULQFLSOHV

© Aarthi Natarajan, 2018 1

The One Constant in software

analysis and design

• What is the one thing you can always count on in
writing software? – Change

© Aarthi Natarajan, 2018 2

Is all about:

• Making sure your software does what the customer wants it to do –
use-case diagram, feature list, prioritise them

• Applying OO design principles to:
– To ensure the system is flexible and extensible to accommodate

changes in requirements

– To strive for a maintainable, reusable, extensible design

Building Good Software

© Aarthi Natarajan, 2018 3

• A change in requirements some-times reveals
problems with your system that you did not even know

that they existed

• Remember, change is constant and your system should
continually improve when you add these
changes…..else software rots

© Aarthi Natarajan, 2018 4

We write bad code

Why do write bad code ?

• Is it because do not know how to write better code?
• Requirements change in ways that original design did not

anticipate

• But changes are not the issue –
• changes requires refactoring and refactoring requires time

and we say we do not have the time

• Business pressure – changes need to be made quickly –
“quick and dirty solutions”

• changes may be made by developers not familiar with the
original design philosophy

Bad code, in fact slows us down

Why does Software Rot?

© Aarthi Natarajan, 2018 5

Design Smells

When software rots

it smells…

A design smell

• is a symptom of poor design
• often caused by violation of key design

principles

• has structures in software that suggest
refactoring

© Aarthi Natarajan, 2018 6

Design Smells (1)

Rigidity

• Tendency of the software being too difficult to change even in
simple ways

• A single change causes a cascade of changes to other dependent
modules

Fragility

• Tendency of the software to break in many places when a single
change is made

Rigidity and fragility complement each other – aim towards

minimal impact, when a new feature or change is needed

© Aarthi Natarajan, 2018 7

Design Smells (2)

Immobility

• Design is hard to reuse
• Design has parts that could be useful to other systems, but

the effort needed and risk in disentangling the system is too

high

Viscosity

• Software viscosity – changes are easier to implement
through ‘hacks’ over ‘design preserving methods’

• Environment viscosity – development environment is slow
and in-efficient

Opacity

• Tendency of a module to be difficult to understand
• Code must be written in a clear and expressive manner

© Aarthi Natarajan, 2018 8

Design Smells (3)
Needless complexity

• Contains constructs that are
not currently useful

• Developers ahead of
requirements

Needless repetition

• Design contains repeated
structures that could

potentially be unified under a

single abstraction

• Bugs found in repeated units
have to be fixed in every

repetition

© Solid Principles and Design Patterns – Ganesh Samarthyam© Aarthi Natarajan, 2018
9

Characteristics of Good Design

So, we know when our design smells…

But how do we measure if a software is well-designed?

The design quality of software is characterised by

• Coupling
• Cohesion

Good software aims for building a system with loose coupling

and high cohesion among its components so that software

entities are:
• Extensible
• Reusable
• Maintainable
• Understandable
• Testable

© Aarthi Natarajan, 2018 10

Coupling

– Is defined as the degree of interdependence between

components or classes

– High coupling occurs when one component A depends on the
internal workings of another component B and is affected by
internal changes to component B

– High coupling leads to a complex system, with difficulties in

maintenance and extension…eventual software rot

– Aim for loosely coupled classes – allows components to be used

and modified independently of each other

– But “zero-coupled” classes are not usable – striking a balance is

an art!
© Aarthi Natarajan, 2018 11

Cohesion
– The degree to which all elements of a component or class or module

work together as a functional unit

– Highly cohesive modules are:

– much easier to maintain and less frequently changed and have
higher probability of reusability

– Think about

– How well the lines of code in a method or function work together
to create a sense of purpose?

– How well do the methods and properties of a class work together
to define a class and its purpose?

– How well do the classes fit together to create modules?

• Again, just like zero-coupling, do not put all the responsibility into a
single class to avoid low cohesion!

© Aarthi Natarajan, 2018 12

And, applying design principles is the key to creating high-quality

software

“Design principles are key notions considered

fundamental to many different software design

approaches and concepts.”

– SWEBOK v3 (2014)

“The critical design tool for software development

is a mind well educated in design principles”

– Craig Larman

© Aarthi Natarajan, 2018 13

What is a “design principle”?

A basic tool or technique that can be applied to designing

or writing code to make software more maintainable,

flexible and extensible

© Aarthi Natarajan, 2018 14

Several Design Principles…One Goal

Good Software
Design

Highly cohesive,

Loosely coupled

systems

Separation of Concerns (SOC)
(Djikstra, 1974)

SOLID
Principles
(next slide)

Design Patterns (GOF)
₋ Program to an interface, not to an

implementation

₋ Object composition over class inheritance

Pragmatic Programming
• DRY

(Don’t Repeat Yourself)

• KISS
(keep it simple, stupid!)

Less Fragile Systems –
( Maintainable,

Reusable

Extensible Code )
© Aarthi Natarajan, 2018 15

SOLID

• Single responsibility principle: A class should only have a
single responsibility.

• Open–closed principle: Software entities should be open for
extension, but closed for modification.

• Liskov substitution principle: Objects in a program should be
replaceable with instances of their subtypes without altering

the correctness of that program.

• Interface segregation principle: Many client-specific
interfaces are better than one general-purpose interface.

• Dependency inversion principle: One should “depend upon
abstractions, [not] concretions.”

© Aarthi Natarajan, 2018 16

When to use design principles

• Design principles help eliminate design smells

• But, don’t apply principles when there no design smells

• Unconditionally conforming to a principle (just because

it is a principle is a mistake)

• Over-conformance leads to the design smell – needless

complexity

© Aarthi Natarajan, 2018 17

Design Principle #1

The Principle of Least Knowledge or Law of Demeter

© Aarthi Natarajan, 2018 18

• Classes should know about and interact with as few classes as
possible

• Reduce the interaction between objects to just a few close
“friends”

• These friends are “immediate friends” or “local objects”

• Helps us to design “loosely coupled” systems so that changes
to one part of the system does not cascade to other parts of
the system

• The principle limits interaction through a set of rules

Design Principle #1

The Principle of Least Knowledge (Law of Demeter) – Talk

only to your friends

© Aarthi Natarajan, 2018 19

A method in an object should only invoke methods of:
• The object itself
• The object passed in as a parameter to the method
• Objects instantiated within the method
• Any component objects
• And not those of objects returned by a method

Don’t dig deep inside your friends for friends of friends of friends

and get in deep conversations with them — don’t do

– e.g. o.get(name).get(thing).remove(node)

The Principle of Least Knowledge

(Law of Demeter)

© Aarthi Natarajan, 2018 20

A method M in an object O can call on any other method
within O itself
• This rule makes logical sense, a method encapsulated within a

class can call any other method that is also encapsulated within
the same class

public class M {
public void methodM() {

this.methodN();
}
public void methodN() {

// do something
}
}

• Here methodM() calls methodN() as both are methods of
the same class

Principle of Least Knowledge, Rule 1:

© Aarthi Natarajan, 2018 21

A method M in an object O can call on any methods of
parameters passed to the method M
• The parameter is local to the method, hence it can be called as a

friend
public class O {

public void M(Friend f) {
// Invoking a method on a parameter passed to the method is
// legal
f.N();
}

public class Friend {

public void N() {
// do something
}
}

Principle of Least Knowledge, Rule 2:

22

A method M can call a method N of another object, if that
object is instantiated within the method M
• The object instantiated is considered “local” just as the object

passed in as a parameter

public class O {

public void M() {
Friend f = new Friend();
// Invoking a method on an object created within the
// method is legal
f.N();

}

public class Friend {
public void N() {
// do something
}

}

Principle of Least Knowledge, Rule 3:

23

Any method M in an object O can call on any methods of any
type of object that is a direct component of O
• This means a method of a class can call methods of classes of its

instance variables

public class O {

public Friend instanceVar = new Friend();

public void M4() {
// Any method can access the methods of the friend class
F through the instance variable “instanceVar”
instanceVar.N();
}

public class Friend {
public void N() {
// do something
}

}

Principle of Least Knowledge, Rule 4:

© Aarthi Natarajan, 2018 24

Well-designed Inheritance

25

Design Principle #2
LSP (Liskov Substitution Principle)

LSP is about well-designed inheritance

Barbara Liskov (1988) wrote:

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 for o2 then S is a subtype of T.

Bob wrote:

subtypes must be substitutable for their base types

Lecture demo: Square vs Rectangle

What is the problem with Square-Rectangle IS A relationship?

© Aarthi Natarajan, 2018 26

Another LSP Example: A board game

LSP reveals hidden problems with the above inheritance structure

Board3D

© Aarthi Natarajan, 2018 27

What are the issues?

LSP reveals hidden problems with the above inheritance structure

Board3D

Board3D

© Aarthi Natarajan, 2018 28

What are the issues?

LSP states that subtypes must be substitutable for their base
types

Board board = new Board3D()

But, when you start to use the instance of Board3D like a Board,
things go wrong

Artillery unit = board.getUnits(8,4)

Inheritance and LSP indicate that any method on Board should be
able to use on a Board3D, and that Board3D can stand in for
Board without any problems, so the above example clearly
violates LSP

Board here is actually
an instance of the sub-
type Board3D

But, what does this
method for a 3D board?

© Aarthi Natarajan, 2018 29

Solve the problem without inheritance

So what options are there besides inheritance?

• Delegation – delegate the functionality to another class
• Composition – reuse behaviour using one or more classes with
composition

Design Principle: Favour composition over inheritance

If you favour delegation, composition over inheritance, your
software will be more flexible, easier to maintain, extend

© Aarthi Natarajan, 2018 30

• The argument list should be exactly the same as that of the
overridden method

• The access level cannot be more restrictive than the overridden
method’s access level.

E.g., if the super class method is declared public then the
overriding method in the sub class cannot be either private or
protected.

• A method declared final cannot be overridden.
• Constructors cannot be overridden.

Rules for Method Overriding

© Aarthi Natarajan, 2018 31

Can static methods be over-ridden?

Static methods can be defined in the sub-class with the same

signature

– This is not overriding, as there is no run-time polymorphism
– The method in the derived class hides the method in the base
class

Lecture demo…

© Aarthi Natarajan, 2018 32

Covariance of return types in the overridden method

• The return type in the overridden method should be the same or
a sub-type of the return type defined in the super-class

• This means that return types in the overridden method may be
narrower than the parent return types

e.g., Assume Cat is a sub class of Animal

Rules for Method Overriding

© Aarthi Natarajan, 2018 33

What about Contra-variance of method arguments in the

overridden method

Can arguments to methods in sub-class be wider than the
arguments passed in the parent’s method ?

Rules for Method Overriding

© Aarthi Natarajan, 2018 34