Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

PATTERNS03 - Behavioural Design Patterns


Published on

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

  • Be the first to comment

  • Be the first to like this

PATTERNS03 - Behavioural Design Patterns

  1. 1. Behavioural Patterns Michael Heron
  2. 2. 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.
  3. 3. 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.
  4. 4. 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.
  5. 5. 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
  6. 6. 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?
  7. 7. 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
  8. 8. The Strategy Pattern public 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(); } }
  9. 9. The Strategy Pattern public 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()); } }
  10. 10. 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.
  11. 11. 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.
  12. 12. 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.
  13. 13. 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.
  14. 14. 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
  15. 15. 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
  16. 16. 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.
  17. 17. 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
  18. 18. Chain of Responsibility public 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; } }
  19. 19. Chain of Responsibility public 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); }
  20. 20. 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.
  21. 21. 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.