patterns03 - behavioural design patterns

21
Behavioural Patterns Michael Heron

Upload: michael-heron

Post on 05-Dec-2014

68 views

Category:

Software


0 download

DESCRIPTION

An introduction to behavioural design patterns in object orientation. Suitable for intermediate to advanced computing students and those studying software engineering.

TRANSCRIPT

Page 1: PATTERNS03 - Behavioural Design Patterns

Behavioural PatternsMichael Heron

Page 2: PATTERNS03 - Behavioural Design Patterns

Introduction Creational patterns handle object creation. Behavioural patterns are used to simplify

the complexities of run-time object relationships.

They are often quite abstract. They trade off design complexity for

developer flexibility. The patterns we will discuss today are the

strategy, the memento and the chain of responsibility.

Page 3: PATTERNS03 - Behavioural Design Patterns

Structural Design Patterns All structural patterns derive from a single

guideline. Isolate variation in classes Create a separate class for each variable

part of a model. If you have a method that must change

dependant on the type of object it is working with… Consider extracting it out and making it a

class of its own.

Page 4: PATTERNS03 - Behavioural Design Patterns

The Strategy Pattern Imagine the following situation.

A simple role-playing game you developed earlier has taken off, big time. It’s time for an expansion.

Your expansion incorporates different kinds of character. Wizards, Witches, Rogues and Assassins

Each can attack, defend, and cast spells. However, different things can happen

depending on what class you are.

Page 5: PATTERNS03 - Behavioural Design Patterns

The Strategy Pattern Wizards can

Attack and cast spells, but can’t defend. Assassins can

Attack and defend, but can’t cast spells Rogues can

Attack and defend, but can’t cast spells Witches can

Defend and cast spells, but can’t attack

Page 6: PATTERNS03 - Behavioural Design Patterns

The Strategy Pattern Each class action is either identical to the others, or

slightly different. Everyone defends the same, but witches cast different

spells to wizards. How do you handle this?

Inheritance? Only works in limited circumstances.

Abstract classes and Interfaces Much duplication across classes.

A combination Can be highly complex and difficult to modify

Something else?

Page 7: PATTERNS03 - Behavioural Design Patterns

The Strategy Pattern The strategy Pattern is used to decouple the

implementation from the context. Somewhat esoteric pattern, but extremely

powerful. It works by giving each of the actions a class of

its own. DefendAction class AttackAction class SpellAction class

Each of these derive from a common base Action

Page 8: PATTERNS03 - Behavioural Design Patterns

The Strategy Patternpublic class CharacterType { private AttackAction myAttack; private DefendAction myDefend; private SpellsAction mySpell; public CharacterType (AttackAction a, DefendAction d, SpellsAction s) { myAttack = a; myDefend = d; mySpell = s; } pubic performAttack() { myAttack.doAttack(); } public performDefence() { myDefend.doDefence(); } public performSpell() { mySpell.castSpell(); }}

Page 9: PATTERNS03 - Behavioural Design Patterns

The Strategy Patternpublic class Rogue extends CharacterType() { public Rogue() { super (new StealthAttack(), new DodgeDefence(), null); }}

public class Wizard extends CharacterType() { public Wizard() { super (new StaffAttack(), null, new DefendSpell()); }}

public class Assassin extends CharacterType() { public Assassin() { super (new DaggerAttack(), new DodgeDefence(), null); }}

public class Witch extends CharacterType() { public Witch() { super (null, new ParryDefence(), new AttackSpell()); }}

Page 10: PATTERNS03 - Behavioural Design Patterns

The Strategy Pattern Structurally, the strategy pattern allows the

developer to resolve several systemic problems in single inheritance languages. C# and Java

At the cost of (often considerable) obfuscation of code, you gain exceptional control over the structure of objects. The easiest way of thinking about it is that

you have functions that can be swapped in and out as needed.

Page 11: PATTERNS03 - Behavioural Design Patterns

The Strategy Pattern This benefit extends beyond compile time.

You can actually ‘hot swap’ methods if needed. That in itself is tremendously powerful.

Imagine for example a new spell in the game we have outlined. Shapeshift into one of the other classes.

Very difficult to do well with most techniques available. Extremely simple using the strategy pattern.

Page 12: PATTERNS03 - Behavioural Design Patterns

Another Example Imagine our simple drawing package.

What if not only the shape was variable, but the algorithm used to draw them was too?

Strategy gives us an easy way of handling that by decoupling the algorithm used to draw the shapes from the classes. Then we can just swap in drawing

algorithms as we need them.

Page 13: PATTERNS03 - Behavioural Design Patterns

The Memento The memento pattern is used to capture

and restore an object’s internal state. Such as when creating a redo/undo facility

in a program. It is a two object pattern.

The originator is the object with the state we wish to capture.

The caretaker is the object that is about to make the change.

Page 14: PATTERNS03 - Behavioural Design Patterns

The Memento The caretaker object asks the originator

for a Memento object. This object should not be manipulated by

the caretaker. Should the caretaker wish to revert any

changes made, it passes the memento object back to the originator.

Care must be taken in relationships more complex than a 1-to-1 mapping

Page 15: PATTERNS03 - Behavioural Design Patterns

The Memento Implementation of the memento is very

context dependant. This is true of all patterns, but especially

so of mementos. Stacking of memento objects permits

successive ‘undo/redo’ operations. Store memento objects in a stack, pop

and push as needed

Page 16: PATTERNS03 - Behavioural Design Patterns

The Memento Complex object relationships may require

more complex Memento structures. Combinations of patterns can help here.

With simple objects, a Memento may be as simple as storing only a single value. For complex objects, a hashmap of values

can be an easily manipulated vehicle. Ideally state changes will be small at any

one time.

Page 17: PATTERNS03 - Behavioural Design Patterns

Chain of Responsibility The Chain of Responsibility pattern allows

for multiple objects interested in an event to be ‘chained’ together. Through a series of predecessor and

successor objects. In certain respects, it’s like a linked list. A message is passed to the first object in

the chain. If it can’t handle it, it passes it on to the next

Page 18: PATTERNS03 - Behavioural Design Patterns

Chain of Responsibilitypublic class BorrowerRisk { private BorrowerRisk predecessor; private BorrowerRisk successor; private int max; public BorrowerRisk (BorrowerRisk p, BorrowerRisk s) { predecessor = p; successor = s; public BorrowerRisk getPredecessor() { return predecessor; public BorrowerRisk getSuccessor() { return successor; } public boolean canBorrow (int amount) { if (amount > max) { if (getPredecessor() != null) { return getPredecessor().canBorrow (amount); } else { return null; } } return true; }}

Page 19: PATTERNS03 - Behavioural Design Patterns

Chain of Responsibilitypublic static void main (String args[]) { BorrowerRisk noRisk; BorrowerRisk lowRisk; BorrowerRisk highRisk; BorrowerRisk yeGodsRisk; boolean canBorrow; noRisk = new BorrowerRisk (null, lowRisk); lowRisk = new BorrowerRisk (noRisk, highRisk); highRisk = new BorrowerRisk (lowRisk, yeGodsRisk); yeGodsRisk = new BorrowerRisk (highRisk, null); canBorrow = noRisk.canBorrow (10000); }

Page 20: PATTERNS03 - Behavioural Design Patterns

Chain of Responsibility Simple overview of functionality.

Chains of Responsibility are very flexible. Easy to include:

Termination conditions Conditional passing of requests Masks and Priority levels Multi-object handling of requests

One example of use would be a flexible logging system. Messages sent along the chain with note of importance.

Each logging objects determines whether the event is important enough to handle.

Help systems are another common example.

Page 21: PATTERNS03 - Behavioural Design Patterns

Summary Behavioural patterns allow you to provide

effective run-time support for complex object communication needs. Some of them allow you to do things that just

can’t be done at compile time at all. The strategy pattern permits ‘hot swapping’ of

algorithms. The memento allows for easy support for

undo/redo The chain of responsibility allows for multi-

facetted handling of messages by objects.