Principles and Patterns 26 February, 2020 Recap Principles - - PowerPoint PPT Presentation

principles and patterns
SMART_READER_LITE
LIVE PREVIEW

Principles and Patterns 26 February, 2020 Recap Principles - - PowerPoint PPT Presentation

Principles and Patterns 26 February, 2020 Recap Principles Patterns Inheritance Anti-patterns Lecture overview agile development agile design principles and patterns software testing Principles and Patterns Recap Principles


slide-1
SLIDE 1
slide-2
SLIDE 2

Principles and Patterns

26 February, 2020

slide-3
SLIDE 3

Recap Principles Patterns Inheritance Anti-patterns

Lecture overview

  • agile development
  • agile design
  • principles and patterns
  • software testing

Principles and Patterns

slide-4
SLIDE 4

Recap Principles Patterns Inheritance Anti-patterns

Lecture overview

  • agile development
  • agile design
  • principles and patterns
  • software testing

Principles and Patterns

slide-5
SLIDE 5

Recap Principles Patterns Inheritance Anti-patterns

Recap: agile development

  • A mindset:
  • Adaptability: be prepared for changing requirements; react to

changes in the world

  • Communication: work closely with the client, communicate

in-team all the time

  • Respect and responsibility: developers have input on planning

and priorities, but are responsible for their results

  • Scrum

Principles and Patterns

slide-6
SLIDE 6

Recap Principles Patterns Inheritance Anti-patterns

Recap: agile design

  • How to write code that supports changing requirements?
  • information hiding
  • low coupling
  • high cohesion
  • Incremental design
  • avoid premature generalisation
  • when a possible improvement presents itself, refactor

Principles and Patterns

slide-7
SLIDE 7

Recap Principles Patterns Inheritance Anti-patterns

Today: principles and patterns

  • Principles: rules you adhere to in your code
  • setting rules can be important in team work
  • tried and tested principles that help keep coupling low and

cohesion high

  • Patterns: standardised solutions
  • often recurring problems have standard solutions
  • note: some modern languages implement patterns as language

features

  • Anti-patterns: bad solutions
  • often recurring problems have bad solutions that are often used

Principles and Patterns

slide-8
SLIDE 8

Recap Principles Patterns Inheritance Anti-patterns

Design and workflow principles to maintain simplicity

  • Principle of Least Astonishment
  • You Aren’t Gonna Need It
  • Once and Only Once
  • Fail Fast
  • Self-Documenting Code
  • Isolate Third-Party Components
  • Limit Published Interfaces

Principles and Patterns

slide-9
SLIDE 9

Recap Principles Patterns Inheritance Anti-patterns

The SOLID principles

  • Single Responsibility Principle
  • Open-Closed Principle
  • Liskov’s Substitution Principle
  • Interface Segregation Principle
  • Dependency Inversion Principle

Principles and Patterns

slide-10
SLIDE 10

Recap Principles Patterns Inheritance Anti-patterns

Single Responsibility Principle

Every module/class should have responsibility over a single part of the functionality, and that responsibility should be entirely encapsulated by the class.

  • A module/class should have only one reason to change.
  • Bad example: a module that compiles and prints a report.
  • Good example: a module that compiles a report.
  • Good example: a module that is responsible for arithmetic

reasoning.

  • large responsibility, but only one responsibility
  • may contain sub-modules for specific sub-responsibilities
  • Note: a responsibility should not contain “and”.

Principles and Patterns

slide-11
SLIDE 11

Recap Principles Patterns Inheritance Anti-patterns

The Open-Closed Principle

Entities should be open for extension, but closed for modification.

  • Extension should not involve/require changing existing code.
  • Original meaning: use inheritance!
  • Meaning changed as programming languages and

methodologies developed.

  • Now: code should rely mostly on interfaces and abstract

classes, which are open for extension. Implementations need not be.

Principles and Patterns

slide-12
SLIDE 12

Recap Principles Patterns Inheritance Anti-patterns

The Open-Closed Principle

class GraphicEditor { public void drawShape(Shape s) { if (s.queryType() == 1) drawRectangle((Rectangle)s); else if (s.queryType() == 2) drawCircle((Circle)s); } public void drawCircle(Circle r) { ... } public void drawRectangle(Rectangle r) { ... } } interface Shape { int queryType(); } class Rectangle implements Shape { ... int queryType() { return 1; } } class Circle extends Shape { ... int queryType() { return 2; } }

Principles and Patterns

slide-13
SLIDE 13

Recap Principles Patterns Inheritance Anti-patterns

The Open-Closed Principle

class GraphicEditor { public void drawShape(Shape s) { s.draw( myCanvas); } } interface Shape { public void draw(Canvas canvas); } class Rectangle implements Shape { ... public void draw(Canvas canvas); } class Circle implements Shape { ... public void draw(Canvas canvas); }

Principles and Patterns

slide-14
SLIDE 14

Recap Principles Patterns Inheritance Anti-patterns

Liskov’s Substitution Principle

(Objects of) sub-classes must be substitutable for (suitable objects

  • f) their base classes without change in behaviour of the overall

program.

Principles and Patterns

slide-15
SLIDE 15

Recap Principles Patterns Inheritance Anti-patterns

Liskov’s Substitution Principle

Given: public class Rectangle { ... public int getHeight() { ... } public int getWidth() { ... } public void setHeight(int height) { ... } public void setWidth(int width) { ... } } We might want to have another, more restricted class of squares.

Principles and Patterns

slide-16
SLIDE 16

Recap Principles Patterns Inheritance Anti-patterns

Liskov’s Substitution Principle

How about: public class Square extends Rectangle { ... public int getHeight() { ... } public int getWidth() { ... } public void setHeight(int height) { // enforce } public void setWidth(int width) { // enforce } } Seems very reasonable relationship, since squares are rectangles. But violates the principle! Not each Square is-a Rectangle.

Principles and Patterns

slide-17
SLIDE 17

Recap Principles Patterns Inheritance Anti-patterns

Interface Segregation Principle

No client should be forced to depend on methods it does not use.

  • Accomplish by splitting large interfaces into role interfaces.

Principles and Patterns

slide-18
SLIDE 18

Recap Principles Patterns Inheritance Anti-patterns

Interface Segregation Principle

public interface Vehicle { void drive(); void refuel(int amount); } public class Car implements Vehicle { void drive() { ... } void refuel(int amount) { ... } } public class Bike implements Vehicle { void drive() { ... } void refuel(int amount) { throw new Exception(); } }

Principles and Patterns

slide-19
SLIDE 19

Recap Principles Patterns Inheritance Anti-patterns

Dependency Inversion Principle

(A) High-level components should not depend on low-level

  • components. Both should depend on abstractions.

(B) Abstractions should not depend on details. Details should depend on abstractions.

Principles and Patterns

slide-20
SLIDE 20

Recap Principles Patterns Inheritance Anti-patterns

Dependency Inversion Principle

(A) High-level components should not depend on low-level

  • components. Both should depend on abstractions.

(B) Abstractions should not depend on details. Details should depend on abstractions.

Principles and Patterns

slide-21
SLIDE 21

Recap Principles Patterns Inheritance Anti-patterns

Dependency Inversion Principle

(A) High-level components should not depend on low-level

  • components. Both should depend on abstractions.

(B) Abstractions should not depend on details. Details should depend on abstractions.

  • Suppose high-level class A depends (via interaction coupling)
  • n low-level class B.
  • If a mechanism in B changes, we should not have to adapt A.
  • Instead, we should have made an abstract interface B′ on

which A depends and which B implements.

  • In essence, it becomes the role of B′′ to capture the

interaction aspect between A and B.

Principles and Patterns

slide-22
SLIDE 22

Recap Principles Patterns Inheritance Anti-patterns

The SOLID principles

  • Single Responsibility Principle
  • Open-Closed Principle
  • Liskov’s Substitution Principle
  • Interface Segregation Principle
  • Dependency Inversion Principle

Principles and Patterns

slide-23
SLIDE 23

Recap Principles Patterns Inheritance Anti-patterns

Honourable mention: Law of Demeter

Don’t talk to strangers!

Method f of class A may only talk to:

  • A itself
  • variables of A
  • global variables
  • the parameters to f
  • any objects created within f

Alternative formulation: use only one dot.

Principles and Patterns

slide-24
SLIDE 24

Recap Principles Patterns Inheritance Anti-patterns

Software design pattern

In software engineering, a software design pattern is a general, reusable solution to a commonly occurring problem within a given context in software design.

  • not code, but rather a kind of template, a standard way of

doing things

  • arguably: a missing programming language feature

Principles and Patterns

slide-25
SLIDE 25

Recap Principles Patterns Inheritance Anti-patterns

Some design patterns

  • Adapter pattern: use a wrapper to convert the interface of a

class without modifying its source code

  • Facade pattern: tidy up the interfaces to a number of related
  • bjects that have often been developed incrementally
  • Closely related: isolate third-party components!
  • Observer pattern: tell several objects that the state of some
  • ther object has changed
  • Decorator pattern: allow for the possibility of extending the

functionality of an existing class at runtime

  • . . .

Principles and Patterns

slide-26
SLIDE 26

Recap Principles Patterns Inheritance Anti-patterns

Some design patterns

  • Adapter pattern: use a wrapper to convert the interface of a

class without modifying its source code

  • Facade pattern: tidy up the interfaces to a number of related
  • bjects that have often been developed incrementally
  • Closely related: isolate third-party components!
  • Observer pattern: tell several objects that the state of some
  • ther object has changed
  • Decorator pattern: allow for the possibility of extending the

functionality of an existing class at runtime

  • . . .

Principles and Patterns

slide-27
SLIDE 27

Recap Principles Patterns Inheritance Anti-patterns

Some design patterns

Principles and Patterns

slide-28
SLIDE 28

Recap Principles Patterns Inheritance Anti-patterns

Some design patterns

Principles and Patterns

slide-29
SLIDE 29

Recap Principles Patterns Inheritance Anti-patterns

Some design patterns

  • Adapter pattern: use a wrapper to convert the interface of a

class without modifying its source code

  • Facade pattern: tidy up the interfaces to a number of related
  • bjects that have often been developed incrementally
  • Closely related: isolate third-party components!
  • Observer pattern: tell several objects that the state of some
  • ther object has changed
  • Decorator pattern: allow for the possibility of extending the

functionality of an existing class at runtime

  • . . .

Principles and Patterns

slide-30
SLIDE 30

Recap Principles Patterns Inheritance Anti-patterns

Some design patterns

  • Adapter pattern: use a wrapper to convert the interface of a

class without modifying its source code

  • Facade pattern: tidy up the interfaces to a number of related
  • bjects that have often been developed incrementally
  • Closely related: isolate third-party components!
  • Observer pattern: tell several objects that the state of some
  • ther object has changed
  • Decorator pattern: allow for the possibility of extending the

functionality of an existing class at runtime

  • . . .

Principles and Patterns

slide-31
SLIDE 31

Recap Principles Patterns Inheritance Anti-patterns

Some design patterns

  • Adapter pattern: use a wrapper to convert the interface of a

class without modifying its source code

  • Facade pattern: tidy up the interfaces to a number of related
  • bjects that have often been developed incrementally
  • Closely related: isolate third-party components!
  • Observer pattern: tell several objects that the state of some
  • ther object has changed
  • Decorator pattern: allow for the possibility of extending the

functionality of an existing class at runtime

  • . . .

Principles and Patterns

slide-32
SLIDE 32

Recap Principles Patterns Inheritance Anti-patterns

Observer Pattern

class A { void update() { ...

  • therClass1.do thing one();
  • therClass2.do thing two();
  • therClass3.do thing three();

} }

Principles and Patterns

slide-33
SLIDE 33

Recap Principles Patterns Inheritance Anti-patterns

Observer Pattern

class A { void notify observers() { for (int i = 0; i < observers; i++) {

  • bservers[i].eventChangeToA();

} } void update() { ... notify observers(); } } class B implements AListener { void eventChangeToA() { do thing one(); } }

Principles and Patterns

slide-34
SLIDE 34

Recap Principles Patterns Inheritance Anti-patterns

Some design patterns

  • Adapter pattern: use a wrapper to convert the interface of a

class without modifying its source code

  • Facade pattern: tidy up the interfaces to a number of related
  • bjects that have often been developed incrementally
  • Closely related: isolate third-party components!
  • Observer pattern: tell several objects that the state of some
  • ther object has changed
  • Decorator pattern: allow for the possibility of extending the

functionality of an existing class at runtime

  • . . .

Principles and Patterns

slide-35
SLIDE 35

Recap Principles Patterns Inheritance Anti-patterns

Decorator pattern

  • KeyComponentInterface
  • KeyComponent implements KeyComponentInterface
  • Decorator implements KeyComponentInterface
  • internally keeps an object component of type

KeyComponentInterface

  • implements all interface functions by forwarding them to

component

  • Extension1(c) inherits Decorator(c), but overrides method x
  • Extension2(c) inherits Decorator(c), but overrides methods y,

z

  • ConcreteDecorator inherits

Extension1(Extension2(KeyComponent))

  • Example: windowing system with configurable borders,

scrollbars

Principles and Patterns

slide-36
SLIDE 36

Recap Principles Patterns Inheritance Anti-patterns

Example: a simple animation

class AnimObject { protected: Position position; Model *model; public: virtual void update() { } virtual void draw() { // draw model } virtual void meet(AnimObject other) { } }

Principles and Patterns

slide-37
SLIDE 37

Recap Principles Patterns Inheritance Anti-patterns

Example: a simple animation

class InvisibleObject : public AnimObject { public: void draw() override { } } class SolidObject : public AnimObject { public: void meet(AnimObject other) {// handle collision} } class MovableObject : public AnimObject { private: Direction direc; int speed; public: void update() { // update position } }

Principles and Patterns

slide-38
SLIDE 38

Recap Principles Patterns Inheritance Anti-patterns

Example: a simple animation

Challenge: how to get a solid movable block?

Principles and Patterns

slide-39
SLIDE 39

Recap Principles Patterns Inheritance Anti-patterns

Example: a simple animation

interface AnimatedObject { void update() { } void draw() { } void meet(AnimatedObject other) { } } class BoringAnimObject implements AnimatedObject { public: void update() { } void draw() { } void meet(AnimatedObject other) { } }

Principles and Patterns

slide-40
SLIDE 40

Recap Principles Patterns Inheritance Anti-patterns

Example: a simple animation

class DecorAnimObject : AnimatedObject { private: AnimatedObject core; public: DecorAnimObject(AnimatedObject c) { core = c; } virtual void update() { core.update(); } virtual void draw() { core.draw(); } virtual void meet(AnimatedObject other) { core.meet(other); } }

Principles and Patterns

slide-41
SLIDE 41

Recap Principles Patterns Inheritance Anti-patterns

Example: a simple animation

class VisibleAnimObject : public DecorAnimObject { private: Model* model; public: VisibleAnimObject(AnimatedObject c) { super(c); } void draw() override { // draw model } } class SolidAnimObject : public DecorAnimObject { public: SolidAnimObject(AnimatedObject c) { super(c); } void meet(AnimatedObject other) { // handle collision } }

Principles and Patterns

slide-42
SLIDE 42

Recap Principles Patterns Inheritance Anti-patterns

Example: a simple animation

Challenge: how to get a solid movable block? Answer (now): new SolidAnimObject(new MovableAnimObject(new BoringAnimObject()));

Principles and Patterns

slide-43
SLIDE 43

Recap Principles Patterns Inheritance Anti-patterns

Exercise: a Pacman game

abstract class GameObject { private: Position position; Model model; public: virtual void update() { } virtual void draw() { // draw model } virtual void meet(GameObject other) { } } Needed objects: Pacman, MeanGhost, EdibleGhost, Obstacle, Food. Your task: design a class technology to do this!

Principles and Patterns

slide-44
SLIDE 44

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

  • Inheritance. . . awesome!

Principles and Patterns

slide-45
SLIDE 45

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

  • Inheritance. . . awesome?

Principles and Patterns

slide-46
SLIDE 46

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

  • Inheritance. . . awesome?
  • hierarchy depth
  • the diamond problem
  • fragile base classes

Principles and Patterns

slide-47
SLIDE 47

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

  • Inheritance. . . awesome?
  • hierarchy depth
  • the diamond problem
  • fragile base classes

Principles and Patterns

slide-48
SLIDE 48

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

Hierarchy depth

Code reuse: I loved that class from my other project! I want to use it in my new project.

Principles and Patterns

slide-49
SLIDE 49

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

Hierarchy depth

Player Living FingerInfo LineEditor HistoryLogger Family Container Race Stats Combatant Caster Object Saveable TheftCallback Effect

Principles and Patterns

slide-50
SLIDE 50

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

  • Inheritance. . . awesome?

The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.

– Joe Armstrong (creator of Erlang)

Principles and Patterns

slide-51
SLIDE 51

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

A deep hierarchy?

Player Living FingerInfo LineEditor HistoryLogger Family Container Race Stats Combatant Caster Object Saveable TheftCallback Effect

Principles and Patterns

slide-52
SLIDE 52

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

A deep hierarchy?

Player Living FingerInfo LineEditor HistoryLogger Family Container Race Stats Combatant Caster Object Saveable TheftCallback Effect

Principles and Patterns

slide-53
SLIDE 53

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

A deep hierarchy?

Player Living FingerInfo LineEditor HistoryLogger Family Container Race Stats Combatant Caster Object Saveable TheftCallback Effect

Principles and Patterns

slide-54
SLIDE 54

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

A deep hierarchy?

  • replacing inheritance by containment does not fix this

problem: to get the monkey we still need to get the whole jungle

  • however, it keeps the interface cleaner, and thus makes it

much easier to see that we can remove certain parts if we are not interested in the corresponding behaviour

Principles and Patterns

slide-55
SLIDE 55

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

  • Inheritance. . . awesome?
  • hierarchy depth
  • the diamond problem
  • fragile base classes

Principles and Patterns

slide-56
SLIDE 56

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

The diamond problem

PoweredDevice Printer Scanner

Principles and Patterns

slide-57
SLIDE 57

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

The diamond problem

PoweredDevice Printer Scanner Copier

Principles and Patterns

slide-58
SLIDE 58

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

The diamond problem

PoweredDevice Printer Scanner Copier void start() { } void start() { }

Principles and Patterns

slide-59
SLIDE 59

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

The diamond solution

  • Just don’t do that.
  • Instead, Copier contains an instance of Printer and an

instance of Scanner, and can forward queries (e.g., void start() { scanner.start(); printer.start(); }).

  • Or indeed: use a Decorator!

Principles and Patterns

slide-60
SLIDE 60

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

The diamond solution with Decorator Pattern

  • interface PoweredDevice { void start(); }
  • class BasePoweredDevice { void start() { ...

} }

  • class Scanner implements PoweredDevice {

PoweredDevice device; Scanner(PoweredDevice pd) { device = pd; } void start() { doScannerStuff(); device.start(); } }

  • class Printer implements PoweredDevice { ...

}

  • void main() {

PoweredDevice copier = new Scanner (new Printer(new BasePoweredDevice)); }

Principles and Patterns

slide-61
SLIDE 61

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

  • Inheritance. . . awesome?
  • hierarchy depth
  • the diamond problem
  • fragile base classes

Principles and Patterns

slide-62
SLIDE 62

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

Fragile base classes

public class Array { private ArrayList<Object> a = new ArrayList<Object>(); public void add(Object element) { a.add(element); } public void addAll(Object elements[]) { for (int i = 0; i < elements.length; ++i) a.add(elements[i]); } }

Principles and Patterns

slide-63
SLIDE 63

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

Fragile base classes

public class ArrayCount extends Array { private int count; @override; public void add(Object element) { super.add(element); count++; } @override; public void addAll(Object elements[]) { super.addAll(elements); count += elements.length; } }

Principles and Patterns

slide-64
SLIDE 64

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

Fragile base classes

public class Array { private ArrayList<Object> a = new ArrayList<Object>(); public void add(Object element) { a.add(element); } public void addAll(Object elements[]) { for (int i = 0; i < elements.length; ++i) a.add(elements[i]); } }

Principles and Patterns

slide-65
SLIDE 65

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

Fragile base classes

public class Array { private ArrayList<Object> a = new ArrayList<Object>(); public void add(Object element) { a.add(element); } public void addAll(Object elements[]) { for (int i = 0; i < elements.length; ++i) a.add(elements[i]); } }

Principles and Patterns

slide-66
SLIDE 66

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

Fragile base classes

public class Array { private ArrayList<Object> a = new ArrayList<Object>(); public void add(Object element) { a.add(element); } public void addAll(Object elements[]) { for (int i = 0; i < elements.length; ++i) add(elements[i]); } }

Principles and Patterns

slide-67
SLIDE 67

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

Fragile base classes

  • A possible solution: use a convention to never call public /

non-final methods in the same class unless specifically indicated.

  • Alternative: contain and delegate.

Principles and Patterns

slide-68
SLIDE 68

Recap Principles Patterns Inheritance Anti-patterns Problems with inheritance.

  • Inheritance. . . awesome?
  • Emerging trend: use containment and delegation over

inheritance.

  • Inherit from interfaces and abstract classes.
  • Inherit only for is-a-kind-of relations.

Principles and Patterns

slide-69
SLIDE 69

Recap Principles Patterns Inheritance Anti-patterns Composition over inheritance.

Composition over inheritance

Because inheritance exposes a subclass to details of its parent’s implementation, it’s often said that “inheritance breaks encapsulation”.

– Gang of Four

  • Inheritance is white-box reuse, composition is black-box reuse.
  • Interfaces offer all the advantages of polymorphism.

(And great flexibility!)

  • Delegation is a powerful method, which can often replace

inheritance.

  • Annoying in some popular languages. Do it regardless.
  • Note: not a blanket “inheritance is bad”!
  • Inheritance is important, particularly for specialisation.
  • Inheritance is, however, overused.

Principles and Patterns

slide-70
SLIDE 70

Recap Principles Patterns Inheritance Anti-patterns Composition over inheritance.

Exercise: the Discworld player object

Player Living Container Object Inventory Dimensions Property Enchantment Effect

Principles and Patterns

slide-71
SLIDE 71

Recap Principles Patterns Inheritance Anti-patterns Composition over inheritance.

Exercise: the Discworld player object

Player Living Container TangibleObject Inventory Dimensions Property Enchantment Effect

Principles and Patterns

slide-72
SLIDE 72

Recap Principles Patterns Inheritance Anti-patterns Composition over inheritance.

Exercise: the Discworld player object

Player Living TangibleObject Container InanimateObject Inventory Dimensions Enchantment Property Effect

Principles and Patterns

slide-73
SLIDE 73

Recap Principles Patterns Inheritance Anti-patterns Stability and dependency

Dependencies

A design is rigid if it cannot be easily changed. Such rigidity is due to the fact that a single change to heavily interdependent software begins a cascade of changes in dependent modules. When the extent of that cascade of change cannot be predicted by the designers or maintainers the impact of the change cannot be

  • estimated. This makes the cost of the change impossible to
  • estimate. Managers, faced with such unpredictability, become

reluctant to authorize changes. Thus the design becomes rigid.

– Robert C. Martin

Principles and Patterns

slide-74
SLIDE 74

Recap Principles Patterns Inheritance Anti-patterns Stability and dependency

Dependencies

Principles and Patterns

slide-75
SLIDE 75

Recap Principles Patterns Inheritance Anti-patterns Stability and dependency

Dependencies

Principles and Patterns

slide-76
SLIDE 76

Recap Principles Patterns Inheritance Anti-patterns Stability and dependency

Dependencies

Why is the new design robust, maintainable, reusable? = ⇒ the targets of the dependencies are stable

  • they depend on nothing at all

interface Writer { public void write(char c); } interface Reader { public char read(); }

  • they are (or might be) used by many other classes

Good dependency: a dependency on something very stable!

Principles and Patterns

slide-77
SLIDE 77

Recap Principles Patterns Inheritance Anti-patterns Stability and dependency

Class categories

  • Sometimes a number of classes are interdependent.
  • Little sense in measuring dependencies between them.
  • Classes in a category:
  • are closed together against any force of change;
  • are reused together;
  • share some common function.

Principles and Patterns

slide-78
SLIDE 78

Recap Principles Patterns Inheritance Anti-patterns Stability and dependency

Some metrics

For a category C of classes:

  • Let Ca be the number of classes outside C that rely on C.
  • Let Ce be the number of classes outside C that C relies on.
  • The instability of C is

Ce Ca + Ce

  • But: not all classes need to be stable!
  • The abstractness of C is

#abstract classes in C #total classes in C

Principles and Patterns

slide-79
SLIDE 79

Recap Principles Patterns Inheritance Anti-patterns Stability and dependency

Some metrics

Principles and Patterns

slide-80
SLIDE 80

Recap Principles Patterns Inheritance Anti-patterns Stability and dependency

Some metrics

Principles and Patterns

slide-81
SLIDE 81

Recap Principles Patterns Inheritance Anti-patterns Stability and dependency

Some metrics

Principles and Patterns

slide-82
SLIDE 82

Recap Principles Patterns Inheritance Anti-patterns Stability and dependency

Some metrics

Principles and Patterns

slide-83
SLIDE 83

Recap Principles Patterns Inheritance Anti-patterns Things to watch out for

Code smells and anti-patterns

  • Code / design smell: a surface indication that usually

corresponds to a deeper problem in the system

  • Anti-pattern: a common response to a recurring problem that

is usually ineffective and potentially counterproductive (Also applicable outside software itself.)

  • Contributes to technical debt.

Principles and Patterns

slide-84
SLIDE 84

Recap Principles Patterns Inheritance Anti-patterns Things to watch out for

Code smells and anti-patterns

Principles and Patterns

slide-85
SLIDE 85

Recap Principles Patterns Inheritance Anti-patterns Things to watch out for

Design / code smells

  • cyclical dependencies
  • inappropriate use of inheritance
  • data clumps (missing abstraction)
  • duplicate code
  • unclear naming
  • contrived complexity
  • God object

Principles and Patterns

slide-86
SLIDE 86

Recap Principles Patterns Inheritance Anti-patterns Things to watch out for

Code smells – practical metrics in BetterCodeHub

  • Code
  • write small units of code (≤ 15 lines per method)
  • write simple units of code (≤ 4 branch points per method)
  • write code once (≤ 6 lines of copied code)
  • keep unit interfaces small (≤ 4 parameters per method)
  • Architecture
  • separate concerns in modules (≤ 400 lines per module)
  • couple components loosely (typically ≤ 10 incoming calls, no

cyclical dependencies)

  • keep architecture components balanced (6-12 top-level

components)

  • keep your codebase small (≤ 200 000 lines of code)
  • Way of Working
  • write automated tests that cover all code
  • leave your code clean (remove inaccessible code)

Principles and Patterns

slide-87
SLIDE 87

Recap Principles Patterns Inheritance Anti-patterns Things to watch out for

Anti-patterns

  • yo-yo problem
  • coding by exception
  • error hiding
  • boat anchor
  • premature optimisation
  • Cargo cult programming
  • Yak shaving

Principles and Patterns

slide-88
SLIDE 88

Recap Principles Patterns Inheritance Anti-patterns Things to watch out for

Management anti-patterns

  • death march: continuing a project that can be easily predicted

to fail

  • feature creep: adding more and more features that aren’t

necessary

  • ninety-nine rule: underestimating remaining time on an

“almost complete” project

  • management by objectives: focusing on metrics rather than

quality

  • seagull management: having managers and employees in

contact only when problems arise

Principles and Patterns

slide-89
SLIDE 89

Recap Principles Patterns Inheritance Anti-patterns Things to watch out for

Some sources

  • Design Patterns: Elements of Reusable Object-Oriented

Software – Gang of Four

  • https://medium.com/@cscalfani/

goodbye-object-oriented-programming-a59cda4c0e53

  • https://linux.ime.usp.br/~joaomm/mac499/arquivos/

referencias/oodmetrics.pdf

  • https://medium.freecodecamp.org/

the-code-im-still-ashamed-of-e4c021dff55e

Principles and Patterns