Presentation is loading. Please wait.

Presentation is loading. Please wait.

Design Patterns II 1. Behavioral Pattern Visitor: intent and structure Represent an operation to be performed on the elements of an object structure.

Similar presentations


Presentation on theme: "Design Patterns II 1. Behavioral Pattern Visitor: intent and structure Represent an operation to be performed on the elements of an object structure."— Presentation transcript:

1 Design Patterns II 1

2 Behavioral Pattern Visitor: intent and structure Represent an operation to be performed on the elements of an object structure. 2

3 Visitor: structure 3

4 Visitor: participants Visitor (IChef)  declares a Visit operation for each class of ConcreteElement in the object structure. The operation's name and signature identifies the class that sends the Visit request to the visitor. ConcreteVisitor (ChefWong, ChefZung)  implements each operation declared by Visitor. Element (AEater)  defines an Accept operation that takes a visitor as an argument. ConcreteElement (Vegetarian, Carnivore )  implements an Accept operation that takes a visitor as an argument. ObjectStructure  may provide a high-level interface to allow the visitor to visit its elements 4

5 Visitor: collaborations 5

6 Visitor: implementation /* Visitor */ interface IChef { String cookVeggie(Vegetarian h, Integer n); String cookMeat(Carnivore h, Integer n); } /* Concrete Visitor 1 */ class ChefWong implements IChef { public String cookVeggie(Vegetarian h, Integer n) { return n + ":" + h.getBroccoli() + ", " + h.getSalt(); } public String cookMeat(Carnivore h, Integer n) { return n + ":" + h.getMeat() + ", " + h.getPepper(); } } /* Concrete Visitor 2 */ class ChefZung implements IChef { public String cookVeggie(Vegetarian h, Integer n) { return n + ":" + h.getCorn() + ", " + h.getSalt(); } public String cookMeat(Carnivore h, Integer n) { return n + ":" + h.getChicken() + ", " + h.getPepper(); } } /* Visitor */ interface IChef { String cookVeggie(Vegetarian h, Integer n); String cookMeat(Carnivore h, Integer n); } /* Concrete Visitor 1 */ class ChefWong implements IChef { public String cookVeggie(Vegetarian h, Integer n) { return n + ":" + h.getBroccoli() + ", " + h.getSalt(); } public String cookMeat(Carnivore h, Integer n) { return n + ":" + h.getMeat() + ", " + h.getPepper(); } } /* Concrete Visitor 2 */ class ChefZung implements IChef { public String cookVeggie(Vegetarian h, Integer n) { return n + ":" + h.getCorn() + ", " + h.getSalt(); } public String cookMeat(Carnivore h, Integer n) { return n + ":" + h.getChicken() + ", " + h.getPepper(); } } 6

7 Visitor: implementation (cont.) /* Element */ abstract class AEater { String getSalt() { return "salt"; } String getPepper() { return "pepper"; } abstract String order(IChef c, Integer n); } /* Concrete Element 1 */ class Vegetarian extends AEater { String getBroccoli() { return "broccoli"; } String getCorn() { return "corn"; } String order(IChef c, Integer n) { return c.cookVeggie(this, n); } } /* Concrete Element 2 */ class Carnivore extends AEater { String getMeat() { return "steak"; } String getChicken() { return "cornish hen"; } String order(IChef c, Integer n) { return c.cookMeat(this, n); } } /* Client */ AEater John = new Carnivore(); AEater Mary = new Vegetarian(); Mary.order(new ChefWong(), 2); John.order(new ChefZung(), 3); /* Element */ abstract class AEater { String getSalt() { return "salt"; } String getPepper() { return "pepper"; } abstract String order(IChef c, Integer n); } /* Concrete Element 1 */ class Vegetarian extends AEater { String getBroccoli() { return "broccoli"; } String getCorn() { return "corn"; } String order(IChef c, Integer n) { return c.cookVeggie(this, n); } } /* Concrete Element 2 */ class Carnivore extends AEater { String getMeat() { return "steak"; } String getChicken() { return "cornish hen"; } String order(IChef c, Integer n) { return c.cookMeat(this, n); } } /* Client */ AEater John = new Carnivore(); AEater Mary = new Vegetarian(); Mary.order(new ChefWong(), 2); John.order(new ChefZung(), 3); 7

8 Visitor: consequences Consequences: Visitor lets you define a new operation without changing the classes of the elements on which it operates. A visitor gathers related operations and separates unrelated ones. Adding new ConcreteElement classes is hard. Visiting across class hierarchies. Accumulating state. Breaking encapsulation. 8

9 Structural Pattern Decorator: intent and structure Decorators provide a flexible alternative to subclassing for extending functionality. 9

10 Decorator: participants Component (Window)  defines the interface for objects that can have responsibilities added to them dynamically. ConcreteComponent (SimpleWindow)  defines an object to which additional responsibilities can be attached. Decorator (WindowDecorator)  maintains a reference to a Component object and defines an interface that conforms to Component's interface. ConcreteDecorator (ScrollBarDecorator, BorderDecorator)  adds responsibilities to the component. 10

11 Decorator: implementation /* Component */ public interface Window { public void draw(); } /* Concrete Component */ public class SimpleWindow implements Window { public void draw() {…} public String toString() { return "Simple window"; } } /* Decorator */ abstract class WindowDecorator implements Window { protected Window w; public WindowDecorator (Window w) { this.w = w; } } /* Concrete Decorator 1 */ class ScrollBarDecorator extends WindowDecorator { public ScrollBarDecorator(Window w) { super(w); } public void draw() { drawScrollBar(); w.draw(); } private void drawScrollBar() {…} public String toString() { return w + " including scroll bar"; } } /* Component */ public interface Window { public void draw(); } /* Concrete Component */ public class SimpleWindow implements Window { public void draw() {…} public String toString() { return "Simple window"; } } /* Decorator */ abstract class WindowDecorator implements Window { protected Window w; public WindowDecorator (Window w) { this.w = w; } } /* Concrete Decorator 1 */ class ScrollBarDecorator extends WindowDecorator { public ScrollBarDecorator(Window w) { super(w); } public void draw() { drawScrollBar(); w.draw(); } private void drawScrollBar() {…} public String toString() { return w + " including scroll bar"; } } 11

12 Decorator: implementation (cont.) /* Concrete Decorator 2 */ public class BorderDecorator extends WindowDecorator { public BorderDecorator(Window w) { super(w); } public void draw() { drawBorder(); w.draw(); } private void drawBorder() {…} public String getDescription(){ return w + " including border"; } } /* Client */ public class Client { public void run() { Window decoratedWindow = new ScrollBarDecorator( new BorderDecorator( new SimpleWindow())); System.out.println(decoratedWindow); } /* Concrete Decorator 2 */ public class BorderDecorator extends WindowDecorator { public BorderDecorator(Window w) { super(w); } public void draw() { drawBorder(); w.draw(); } private void drawBorder() {…} public String getDescription(){ return w + " including border"; } } /* Client */ public class Client { public void run() { Window decoratedWindow = new ScrollBarDecorator( new BorderDecorator( new SimpleWindow())); System.out.println(decoratedWindow); } 12

13 Decorator: consequences Consequences: More flexibility than static inheritance. Avoids feature-laden classes high up in the hierarchy. A decorator and its component aren't identical. Lots of little objects. 13

14 Structural Pattern Adapter: intent and structure Convert the interface of a class into another interface clients expect. 14

15 Adapter: participants Target (Stack)  defines the domain-specific interface that Client uses. Client  collaborates with objects conforming to the Target interface. Adaptee (DList)  defines an existing interface that needs adapting. Adapter (DListImpStack)  adapts the interface of Adaptee to the Target interface. 15

16 Class Adapter: implementation /* Target */ interface Stack { void push (T o); T pop (); T top (); } /* Adaptee */ public class DList { public void insertHead (T o) {…} public void insertTail (T o) {…} public T removeHead () {…} public T removeTail () {…} public T getHead () {…} public T getTail () {…} } /* Adapter */ public class DListImpStack extends DList implements Stack { public void push (T o) { insertTail (o); } public T pop () { return removeTail (); } public T top () { return getTail (); } } /* Target */ interface Stack { void push (T o); T pop (); T top (); } /* Adaptee */ public class DList { public void insertHead (T o) {…} public void insertTail (T o) {…} public T removeHead () {…} public T removeTail () {…} public T getHead () {…} public T getTail () {…} } /* Adapter */ public class DListImpStack extends DList implements Stack { public void push (T o) { insertTail (o); } public T pop () { return removeTail (); } public T top () { return getTail (); } } 16

17 Adapter: consequences Consequences: A class adapter a class adapter won't work when we want to adapt a class and all its subclasses. lets Adapter override some of Adaptee's behavior no additional pointer indirection is needed to get to the adaptee. An object adapter lets a single Adapter work with many Adaptees makes it harder to override Adaptee behavior. 17

18 Behavioral Pattern Command: intent and structure Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations. 18

19 Command: participants Command (Command)  declares an interface for executing an operation. ConcreteCommand (MoveUpCommand, MoveRightCommand)  defines a binding between a Receiver object and an action.  implements Execute by invoking the corresponding operation(s) on Receiver. Client (Game)  creates a ConcreteCommand object and sets its receiver. Invoker (Game)  asks the command to carry out the request. Receiver (GameBoard)  knows how to perform the operations associated with carrying out a request. Any class may serve as a Receiver. 19

20 Command: implementation /* Receiver */ public class GameBoard { public int x = 0; public int y = 0; public static final int XMAX = 10; public static final int YMAX = 10; public void incX() { if (x < GameBoard.XMAX) ++x; } public void decX() { if (x > 0) --x; } public void incY() { if (y < GameBoard.YMAX) ++y; } public void decY() { if (y > 0) --y; } } /* Command */ public interface Command { void execute(); void undo(); } /* Concrete Command 1 */ public class MoveUpCommand implements Command { private GameBoard gb; public MoveUpCommand(GameBoard gb) { this.gb = gb; } public void execute() { gb.incY(); } public void undo() { gb.decY(); } } /* Receiver */ public class GameBoard { public int x = 0; public int y = 0; public static final int XMAX = 10; public static final int YMAX = 10; public void incX() { if (x < GameBoard.XMAX) ++x; } public void decX() { if (x > 0) --x; } public void incY() { if (y < GameBoard.YMAX) ++y; } public void decY() { if (y > 0) --y; } } /* Command */ public interface Command { void execute(); void undo(); } /* Concrete Command 1 */ public class MoveUpCommand implements Command { private GameBoard gb; public MoveUpCommand(GameBoard gb) { this.gb = gb; } public void execute() { gb.incY(); } public void undo() { gb.decY(); } } 20

21 Command: implementation (cont.) /* Concrete Command 2 */ public class MoveRightCommand implements Command { private GameBoard gb; public MoveRightCommand (GameBoard gb) { this.gb = gb; } public void execute() { gb.incX(); } public void undo() { gb.decX();} } /* Invoker */ public class Game { private GameBoard gb = new GameBoard(); private Command moveUpCommand; private Command moveLeftCommand; public Game() { moveUpCommand = new MoveUpCommand(gb); moveLeftCommand = new MoveRightCommand(gb); } public void action() { moveUpCommand.execute(); moveLeftCommand.execute(); } /* Concrete Command 2 */ public class MoveRightCommand implements Command { private GameBoard gb; public MoveRightCommand (GameBoard gb) { this.gb = gb; } public void execute() { gb.incX(); } public void undo() { gb.decX();} } /* Invoker */ public class Game { private GameBoard gb = new GameBoard(); private Command moveUpCommand; private Command moveLeftCommand; public Game() { moveUpCommand = new MoveUpCommand(gb); moveLeftCommand = new MoveRightCommand(gb); } public void action() { moveUpCommand.execute(); moveLeftCommand.execute(); } 21

22 Command: consequences Consequences: Command decouples the object that invokes the operation from the one that knows how to perform it. Commands are first-class objects. They can be manipulated and extended like any other object. You can assemble commands into a composite command. It's easy to add new Commands, because you don't have to change existing classes. 22

23 Behavioral Pattern Observer: intent and structure Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. 23

24 Observer: participants Subject  knows its observers. Any number of Observer objects may observe a subject.  provides an interface for attaching and detaching Observer objects. ConcreteSubject (PowerVector)  stores state of interest to ConcreteObserver objects.  sends a notification to its observers when its state changes. Observer (IObserver)  defines an updating interface for objects that should be notified of changes in a subject. ConcreteObserver (SizeKeeper)  maintains a reference to a ConcreteSubject object.  stores state that should stay consistent with the subject's.  implements the Observer updating interface to keep its state consistent with the subject's. 24

25 Observer: implementation /* Concrete Subject */ public class PowerVector { private ArrayList items = new ArrayList (); private ArrayList observers = new ArrayList (); public int size() { return items.size(); } public void addObserver(IObserver ob) { observers.add(ob); } public void add(Object o) { items.add(o); notifyObservers(); } public void remove(Object o) { items.remove(o); notifyObservers(); } public void notifyObservers() { for (IObserver ob: observers) ob.update(this); } /* Concrete Subject */ public class PowerVector { private ArrayList items = new ArrayList (); private ArrayList observers = new ArrayList (); public int size() { return items.size(); } public void addObserver(IObserver ob) { observers.add(ob); } public void add(Object o) { items.add(o); notifyObservers(); } public void remove(Object o) { items.remove(o); notifyObservers(); } public void notifyObservers() { for (IObserver ob: observers) ob.update(this); } 25

26 Observer: implementation (cont.) /* Observer */ public interface IObserver { public void update(PowerVector subject); } /* Concrete Observer */ public class SizeKeeper implements IObserver { private int size; public void update(PowerVector subject) { size = subject.size(); } public int size() { return size; } } /* Client */ public class Client { private PowerVector v = new PowerVector(); public void run(){ v.addObserver(new SizeKeeper()); v.add(1); v.add(2); System.out.println(v.size()); } /* Observer */ public interface IObserver { public void update(PowerVector subject); } /* Concrete Observer */ public class SizeKeeper implements IObserver { private int size; public void update(PowerVector subject) { size = subject.size(); } public int size() { return size; } } /* Client */ public class Client { private PowerVector v = new PowerVector(); public void run(){ v.addObserver(new SizeKeeper()); v.add(1); v.add(2); System.out.println(v.size()); } 26

27 Observer: consequences Consequences: Abstract coupling between Subject and Observer. Support for broadcast communication. Unexpected updates. 27

28 Behavioral Pattern Chain-of-Responsibility: intent and structure Chain the receiving objects and pass the request along the chain until an object handles it. 28

29 Chain-of-Responsibility: participants Handler (Filter)  defines an interface for handling requests.  (optional) implements the successor link. ConcreteHandler (EvenFilter, PrimeFilter)  handles requests it is responsible for.  can access its successor.  if the ConcreteHandler can handle the request, it does so; otherwise it forwards the request to its successor. Client (Client)  initiates the request to a ConcreteHandler object on the chain. 29

30 Chain-of-Responsibility: implementation /* Handler */ public class Filter { private Filter next = null; public void attach(Filter other) { other.next = this.next; this.next = other; } public final void invoke(int v) { if (this.handle(v)) return; if (next != null) next.invoke(v); } public boolean handle(int v) { return false;} } /* Concrete Handler 1 */ public class EvenFilter extends Filter { public boolean handle(int v) { return (v % 2 == 0);} } /* Concrete Handler 2 */ public class PrimeFilter extends Filter { public boolean handle(int v) { for (int i = 2; i * i <= v; ++i) if (v % i == 0) return false; return true; } /* Handler */ public class Filter { private Filter next = null; public void attach(Filter other) { other.next = this.next; this.next = other; } public final void invoke(int v) { if (this.handle(v)) return; if (next != null) next.invoke(v); } public boolean handle(int v) { return false;} } /* Concrete Handler 1 */ public class EvenFilter extends Filter { public boolean handle(int v) { return (v % 2 == 0);} } /* Concrete Handler 2 */ public class PrimeFilter extends Filter { public boolean handle(int v) { for (int i = 2; i * i <= v; ++i) if (v % i == 0) return false; return true; } 30

31 Chain-of-Responsibility: implementation (cont.) /* Client */ public class Client { private ArrayList l = new ArrayList (); private Filter chain = new Filter(); public Client() { chain.attach(new Filter() { public boolean handle(int v) { l.add(v); return true; } }); chain.attach(new EvenFilter()); chain.attach(new PrimeFilter()); } public void run() { for (int i = 0; i < 10; ++i) chain.invoke(i); System.out.println("Size = " + l.size()); } /* Client */ public class Client { private ArrayList l = new ArrayList (); private Filter chain = new Filter(); public Client() { chain.attach(new Filter() { public boolean handle(int v) { l.add(v); return true; } }); chain.attach(new EvenFilter()); chain.attach(new PrimeFilter()); } public void run() { for (int i = 0; i < 10; ++i) chain.invoke(i); System.out.println("Size = " + l.size()); } 31

32 Chain-of-Responsibility: consequences Consequences: Reduced coupling. Added flexibility in assigning responsibilities to objects. Receipt isn't guaranteed. 32


Download ppt "Design Patterns II 1. Behavioral Pattern Visitor: intent and structure Represent an operation to be performed on the elements of an object structure."

Similar presentations


Ads by Google