12
1 Computing Science & Mathematics University of Stirling 1 Design Patterns ITNP90 - Object Oriented Software Design Dr Sandy Brownlee 4B69 [email protected] Computing Science & Mathematics University of Stirling 2 Design Patterns: overview • Introduction Managing change Concepts & principles Design Patterns Structural Patterns Composite Adapter Decorator • Behavioural Patterns Strategy • Observer • Command • Creational Patterns Singleton • Factory Computing Science & Mathematics University of Stirling Motivation What's the one constant in software development? We will illustrate this with an example… DuckSim is a game that shows various ducks swimming around a virtual pond. It was built using OO techniques, With all duck types inheriting from The Duck superclass. The head of the company wants a new feature: flying ducks. Example from: Head First Design Patterns, Freeman et al 3 Change Computing Science & Mathematics University of Stirling Managing change We could add a fly() method to Duck, so that all the duck types inherit the ability to fly: an example of reuse 4

Design Patterns: overvie · 2017-03-29 · Design Patterns ITNP90 - Object Oriented Software Design ... object modelling, class / use-case / state / sequence diagrams. We have seen

  • Upload
    others

  • View
    5

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Design Patterns: overvie · 2017-03-29 · Design Patterns ITNP90 - Object Oriented Software Design ... object modelling, class / use-case / state / sequence diagrams. We have seen

1

Computing Science & MathematicsUniversity of Stirling

1

Design Patterns ITNP90 - Object Oriented Software Design

Dr Sandy Brownlee4B69 [email protected]

Computing Science & MathematicsUniversity of Stirling

2

Design Patterns: overview• Introduction

• Managing change• Concepts & principles• Design Patterns

• Structural Patterns• Composite• Adapter• Decorator

• Behavioural Patterns• Strategy• Observer • Command

• Creational Patterns• Singleton• Factory

Computing Science & MathematicsUniversity of Stirling

MotivationWhat's the one constant in software development?

We will illustrate this with an example…

DuckSim is a game that shows various ducksswimming around a virtual pond.

It was built using OO techniques,With all duck types inheriting fromThe Duck superclass.

The head of the company wantsa new feature: flying ducks.

Example from: Head First Design Patterns, Freeman et al

3

Change

Computing Science & MathematicsUniversity of Stirling

Managing change

We could add a fly() methodto Duck, so that all the ducktypes inherit the ability to fly:an example of reuse

4

Page 2: Design Patterns: overvie · 2017-03-29 · Design Patterns ITNP90 - Object Oriented Software Design ... object modelling, class / use-case / state / sequence diagrams. We have seen

2

Computing Science & MathematicsUniversity of Stirling

5

Managing changeUnfortunately, we didn't notice a recentaddition to the game: rubber ducks. Nowthey are flying too!

This is an unintended side-effect of ourchange, arising from the use of inheritance

We could override fly() for inanimate ducks,but this means duplicate code, defeatingthe point of inheritance.

Computing Science & MathematicsUniversity of Stirling

Managing changeWe could specify an interface, which only flying ducks implement. The same could apply to quack() to allow silent ducks. What is wrong with this design?

6

The problem is that now we have to implement a fly() method for every flying duck. This gets more complicated if other methods like quack() and swim() are optional too.

Computing Science & MathematicsUniversity of Stirling

Managing changeWe need a way to capture the parts of the system that vary and separate them out from the parts that stay the same.

We know that we have some duck behaviours which vary:• A duck's flying behaviour can be to fly, or not fly• A duck's quacking behaviour can be to quack, squeak, or be silent

Let's capture these behaviours in separate classes:

7 Computing Science & MathematicsUniversity of Stirling

Managing changeWe can now change the relationship so "duck type" HAS-A "behaviour":

8

Page 3: Design Patterns: overvie · 2017-03-29 · Design Patterns ITNP90 - Object Oriented Software Design ... object modelling, class / use-case / state / sequence diagrams. We have seen

3

Computing Science & MathematicsUniversity of Stirling

Managing changeWe have used a technique called composition to get the desired behaviour for our ducks.

This means that we can all the benefits of reuse, but also greatly increased flexibility. We can even change the behaviours of a duck at runtime!

We've also seen two design principles which are very useful in designing applications that are more maintainable:

1. Program to an interface, not an implementation

2. Favour object composition over inheritance

These are not hard rules, but useful guidelines for developing an OO system.

9 Computing Science & MathematicsUniversity of Stirling

Principle 1"Program to an interface, not an implementation"

• In our DuckSim example, the Duck superclass has a reference to an object implementing the FlyBehaviour interface

• The Duck object calls the fly() method in this interface• What actually happens is dependent on whether the object is a

FlyWithWings or FlyNever object; the duck is unaware of the specific implementation that is used

In practice, what this means is that we should always use variables with as abstract a type as possible. This reduces dependence on implementations, making the code more open to future changes.

Note: here, "interface" really means supertype: it could be an Interface, an abstract class or a concrete class in practice (don't confuse with the Java "interface")

10

Computing Science & MathematicsUniversity of Stirling

Principle 1"Program to an interface, not an implementation"

An example based on DuckSim:

FlyWithWings myBehaviour = new FlyWithWings();

we will be tied to using the FlyWithWings implementation. This might lead to problems if we change to FlyNever in the future. We should do this:

FlyBehaviour myBehaviour = new FlyWithWings();

This will allow us to easily change implementation without changing the code:

FlyBehaviour myBehaviour = new FlyNever();

11 Computing Science & MathematicsUniversity of Stirling

Principle 1"Program to an interface, not an implementation"

Example for the Java programmers: our application needs a reference to a List to store several objects. If we write this:

ArrayList myList = new ArrayList();

we will be tied to using the ArrayList implementation, which is good for random access, but not so good at accommodating growth. We should do this:

List myList = new ArrayList();

This will allow us to easily change implementation without changing the code:

List myList = new LinkedList();

12

Page 4: Design Patterns: overvie · 2017-03-29 · Design Patterns ITNP90 - Object Oriented Software Design ... object modelling, class / use-case / state / sequence diagrams. We have seen

4

Computing Science & MathematicsUniversity of Stirling

Principle 2"Favour object composition over class inheritance"

• In our DuckSim example, we composed the behaviour for the ducks, by using references to Behaviour objects.

• Duck objects delegate the implementation of flying and quacking to their Behaviour object

Inheritance has its place: it is defined statically at compile-time (so your IDE can help you) and is straightforward to use. However, it can lead to side-effects if we override some parts of behaviour but not others.

Object composition allows new functionality to be obtained by assembling or composing existing objects to get more functionality. It can be done dynamically at run-time, and allows for much greater flexibility.

13 Computing Science & MathematicsUniversity of Stirling

14

Re-using experienceSo far in this module, we have covered several aspects of OO design: object modelling, class / use-case / state / sequence diagrams.

We have seen some pitfalls of a poor object model, and principles that can help, but in general, how do we decide what makes a good object model?

– What guidance do we have about the kind of object that we expect to find in a object model?

– It is always much easier to solve a problem if you have previously solved similar problems or, at least, have access to a solution to a similar problem.

– The final duck behaviour solution was not obvious, but it might be useful in other contexts. In fact, it was an example of a Design Pattern – specifically, the Strategy Pattern.

– Design Patterns are a major topic in object modelling. They allow beginners to benefit from the previous experience of experts when solving problems.

Computing Science & MathematicsUniversity of Stirling

15

Design Patterns

[1977] Alexander's work on urban planning and building architecture: Patterns have a tradition in design/project disciplines.

[OOPSLA 1987] Beck & Cunningham the idea of applying patterns to programming at the ACM Object Oriented Programming Systems and Applications conference.

[1995] Gamma, Helm, Johnson & Vlissides (1995). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley. Often referred to as the GoF (Gang of Four) book:this book made design patterns popular in computer science

Lots of online documentation online: try to find your sources!

Computing Science & MathematicsUniversity of Stirling

16

Design PatternsUML designers' definition:

"A pattern is a common solution to a common problem in a given context.”

Wikipedia's definition:

"In software engineering, a design pattern is a general reusable solution to a commonly occurring problem in software design. ... is not a finished design ... it ... is a description or template for how to solve a problem that can be used in many different situations.

Object-oriented design patterns typically show relationships and interactions between classes or objects."

(Compare these definitions with the usage of the MVC framework for the Noughts and Crosses case study).

Page 5: Design Patterns: overvie · 2017-03-29 · Design Patterns ITNP90 - Object Oriented Software Design ... object modelling, class / use-case / state / sequence diagrams. We have seen

5

Computing Science & MathematicsUniversity of Stirling

17

Design Patterns

Following the principle of reuse, it would be wise to precisely describe such a pattern, or better, a well-tested and commonly agreed version of such a pattern, so as to be able

– to easily recognise when it can be applied to a given scenario, and

– to straightforwardly apply it to our system design.

More in general it would be desirable to have a library or catalogue of such design patterns. These embed the principles we discussed earlier.

As well as general catalogues, many have been developed for specific domains: user interfaces, concurrency, … , metaheuristics (MetaDeeP workshops)

Computing Science & MathematicsUniversity of Stirling

18

Description of PatternsPattern catalogues have been produced. Several different descriptions of design patterns, some prevailing in practice, e.g. from Design Patterns (GoF):

Pattern name: A descriptive and unique name. Intent: Goals of the patterns and reasons for using it.Motivation -forces: A scenario, ie a problem and a context, in which the pattern can be used.Applicability: Situations and contexts for pattern usage.Structure: A graphical representation (Class and Interaction diagrams).Participants: Cases and objects used in the pattern and their roles.Collaboration: How patterns' classes and objects interact with each other.Consequences: A description of the results, side effects, and trade offs of the pattern.Implementation: A description of an implementation of the pattern. Sample Code: An illustration the pattern's uses in programming languages.Known Uses: Examples of real usages of the pattern.Related Patterns: Other similar patterns.

Computing Science & MathematicsUniversity of Stirling

19

Classes of Patterns

Main classification:

Behavioural Patterns (interaction, eg. Observer),

Structural (class/objects structure, eg. Adapter, Composite) and

Creational (creating objects, eg. Factory Method).

Computing Science & MathematicsUniversity of Stirling

Selecting a design pattern• Consider what changes and what is static in your application

• Scan the intent sections in the catalogue, then motivation and applicability for confirmation

• Study how the patterns interrelate: the GoF patterns have a related patterns section and an overall illustration

• Study patterns of a similar purpose / class

20

Page 6: Design Patterns: overvie · 2017-03-29 · Design Patterns ITNP90 - Object Oriented Software Design ... object modelling, class / use-case / state / sequence diagrams. We have seen

6

Computing Science & MathematicsUniversity of Stirling

21

Design Patterns: overview• Introduction

• Managing change• Concepts & principles• Design Patterns

• Structural Patterns• Composite• Adapter• Decorator

• Behavioural Patterns• Strategy• Observer • Command

• Creational Patterns• Singleton• Factory

Computing Science & MathematicsUniversity of Stirling

22

Design Patterns

Strategy

Computing Science & MathematicsUniversity of Stirling

StrategyMotivation (scenario): • Many algorithms exist for doing the same job• E.g. sorting a list; encrypting data; layout of GUI components• We want to be able to easily change from one algorithm to another

We used the Strategy Pattern to solve our DuckSim problem earlier.

The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from the clients that use it.

23 Computing Science & MathematicsUniversity of Stirling

Strategy• Taking the earlier example, and making it more general:

• Behaviours become algorithms• Duck becomes the context

24

Page 7: Design Patterns: overvie · 2017-03-29 · Design Patterns ITNP90 - Object Oriented Software Design ... object modelling, class / use-case / state / sequence diagrams. We have seen

7

Computing Science & MathematicsUniversity of Stirling

StrategyStructure• Each algorithm or strategy is wrapped up in a class that implements a

common interface• The Context class is configured with a Strategy object, and keeps a

reference to it• Context might also define an interface that lets strategy access its data

25 Computing Science & MathematicsUniversity of Stirling

Comparing objectsA commonly-used example of the Strategy pattern in Java is the Comparator interface. This is used to compare two objects A & B, returning:• Negative if A < B• Zero if A == B• Positive if A > B

List<Integer> l =

Arrays.asList(new Integer[]{3,7,4,9,4,6,2});

Collections.sort(l, new Ascending());

public class Ascending implements Comparator {

public int compare(Object o1, Object o2) {

return ((Integer)o1) - ((Integer)o2);

}

}

public class Descending implements Comparator {

public int compare(Object o1, Object o2) {

return ((Integer)o2) - ((Integer)o1);

}

}26

Computing Science & MathematicsUniversity of Stirling

27

Design Patterns

Observer

Computing Science & MathematicsUniversity of Stirling

28

ObserverAlso known as: publisher–subscriber; listener

Motivation (scenario): – An object needs to inform other objects when it has changed– Observers register with a subject: when the subject has some new information,

all its observers are informed.– We have the interfaces Subject and Observer and the concrete classes

ConcreteSubject and ConcreteObserver.

The Observer Pattern defines a one-to-many dependency between objects so that

when one object changes state, all its dependents are notified and updated

automatically.

Page 8: Design Patterns: overvie · 2017-03-29 · Design Patterns ITNP90 - Object Oriented Software Design ... object modelling, class / use-case / state / sequence diagrams. We have seen

8

Computing Science & MathematicsUniversity of Stirling

29

ObserverStructure:

– A ConcreteObserver object registers with a ConcreteSubject object using the registerObserver() method defined in the superclass Subject.

– Each ConcreteSubject object maintains a list of all the ConcreteObserverobjects that have registered with it.

Computing Science & MathematicsUniversity of Stirling

30

ObserverStructure:

– The writer of the ConcreteSubject subclass does not need to know anything about the details of ConcreteObserver

– When a ConcreteSubject object has new information, it calls its notifyObservers() operation (defined in its Subject interface).

Computing Science & MathematicsUniversity of Stirling

31

ObserverStructure:

– This causes an update message to be sent to all its registered subscribers.– Each ConcreteObserver object can then call the getState() operation in

the ConcreteSubject object to get the new information.

Computing Science & MathematicsUniversity of Stirling

32

ObserverThere are two important sequence diagrams for Observer:

Register Update

Clearly, Observer is very similar to the MVC.

notifyObservers

Page 9: Design Patterns: overvie · 2017-03-29 · Design Patterns ITNP90 - Object Oriented Software Design ... object modelling, class / use-case / state / sequence diagrams. We have seen

9

Computing Science & MathematicsUniversity of Stirling

33

The class diagram on this slide represents the support for the Observer pattern, from a Java perspective.

The abstract superclassObservable (subject) and the interface Observer are defined in the Java library.

http://download.oracle.com/javase/6/docs/api/java/util/Observable.html

Observer Pattern and Java

Computing Science & MathematicsUniversity of Stirling

34

Graphical User Interfaces

A program with a Graphical User Interface (GUI) is event-driven.

– It waits for an event (such as a button press) to occur, handles the event and then waits for the next event.

– Events are handled within an event loop.

This is a natural application for the Observer design pattern.

Computing Science & MathematicsUniversity of Stirling

35

Graphical User InterfaceExample: as seen, in Java to be able to handle events an object must be declared

to be an EventListener (i.e. like an observer) and must register itself with the graphical objects (the subjects) that can generate the events in which it is interested.

This can be easily be thought in terms of Observer:

For instance (considering a generic Boundary class)

public class Boundary …implements ActionListener

...

(ActionListener is a sub interface of EventListener)

ActionListener

Computing Science & MathematicsUniversity of Stirling

36

Graphical User Interface... and a Boundary object that registers itself with a graphical component Button component, a aButton object say, by calling

aButton.addActionListener(this);

The aBoundary event listener object then contains the definition of anappropriate event handler, e.g. in our case the method

void actionPerformed

(ActionEvent e)

When a button is pressed, the aButton object informs all its registered event listeners by calling their actionPerformedmethod.

ActionListener

Page 10: Design Patterns: overvie · 2017-03-29 · Design Patterns ITNP90 - Object Oriented Software Design ... object modelling, class / use-case / state / sequence diagrams. We have seen

10

Computing Science & MathematicsUniversity of Stirling

37

Design Patterns

Command

Computing Science & MathematicsUniversity of Stirling

CommandAlso known as: Transaction

Motivation (scenario): • We want to issue requests to objects without knowing anything about

them (what they do, how they do it)• For example: a user interface library will have menu item objects that will

perform an action when clicked on: but they won't have the action implemented directly within them

• We might also want to keep track of requests, so we can log them, queue them, or undo them (roll them back)

The Command Pattern encapsulates a request as an object, allowing us to: parameterise clients with different requests; queue or log requests; and support undoable operations.

38

Computing Science & MathematicsUniversity of Stirling

Command• Command looks quite similar to Observer• Structurally, it is quite similar, but they differ in intent• Command models an action that you need more to do with than just

execute it now• Observer is used when a Subject needs to notify other objects about

events, but doesn't know which objects to notify

39 Computing Science & MathematicsUniversity of Stirling

CommandStructure• The Invoker holds a command and at some point asks the command

to carry out a request by calling its execute() method• The ConcreteCommand represents a binding between an action and

the receiver. When the Invoker makes a request by calling execute(), ConcreteCommand carries it out by calling methods on the Receiver

40

Page 11: Design Patterns: overvie · 2017-03-29 · Design Patterns ITNP90 - Object Oriented Software Design ... object modelling, class / use-case / state / sequence diagrams. We have seen

11

Computing Science & MathematicsUniversity of Stirling

CommandStructure• The Receiver class actually does the work: it can be anything• The Client creates a ConcreteCommand object and sets its receiver

41 Computing Science & MathematicsUniversity of Stirling

CommandSequence diagram

42

new Client() user

invoke()

Computing Science & MathematicsUniversity of Stirling

Example: universal controller• We have a Light class, the Receiver• RemoteControl is the invoker

RemoteControl rc = new RemoteControl();

rc.setCommand("Button1", new LightOn());

rc.setCommand("Button2", new LightOff());

------------------------------------------

private interface Command {

public void execute();

public void undo();

}

------------------------------------------

public class LightOn implements Command {

public void execute() {

Light.on();

}

public void undo() {

Light.off();

}

}43

maplin.co.uk

Button1

Button2

Button3

Computing Science & MathematicsUniversity of Stirling

Example: universal controller• We have a Light class, the Receiver• RemoteControl is the invoker

RemoteControl rc = new RemoteControl();

rc.setCommand("Button1", new LightOn());

rc.setCommand("Button2", new LightOff());

------------------------------------------

private interface Command {

public void execute();

public void undo();

}

------------------------------------------

public class LightOff implements Command {

public void execute() {

Light.off();

}

public void undo() {

Light.on();

}

}44

maplin.co.uk

Button1

Button2

Button3

Page 12: Design Patterns: overvie · 2017-03-29 · Design Patterns ITNP90 - Object Oriented Software Design ... object modelling, class / use-case / state / sequence diagrams. We have seen

12

Computing Science & MathematicsUniversity of Stirling

Example: universal controller• The invoker will always call execute()• This could cause an exception if the slot is

empty (NullPointerException in Java)• The DoNothing class can be used to fill

blank slots. It simply does nothing when execute() is called.

• DoNothing is an example of a Null Object: null objects are sometimes listed as design patterns themselves

rc.setCommand("Button3", new DoNothing());

------------------------------------------

public class DoNothing implements Command {

public void execute() {

/*do nothing*/

}

public void undo() {

/*do nothing*/

}

}45

maplin.co.uk

Button1

Button2

Button3

Computing Science & MathematicsUniversity of Stirling

CommandDCommandF

CommandHow might we implement an undo function?

46

• Use a stack• This is a last-in-first-out data structure • Each time we run a command, we call

execute() on it and "push" it onto the stack• Each time we undo, we "pop" the top command

of the stack, and call undo() on it• This can mean that commands need to store

the previous state so it can be retrieved as part of undo()

CommandA

CommandB

CommandC

CommandECommandG

Computing Science & MathematicsUniversity of Stirling

47

Design Patterns: overview• Introduction

• Managing change• Concepts & principles• Design Patterns

• Structural Patterns• Composite• Adapter• Decorator

• Behavioural Patterns• Strategy• Observer • Command

• Creational Patterns• Singleton• Factory