design patterns elements of reusable object-oriented software by erich gamma, richard helm, ralph...

19
Design Patterns Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson , and John Vlissides (The Gang of Four ).

Post on 21-Dec-2015

229 views

Category:

Documents


1 download

TRANSCRIPT

Design Patterns

Elements of Reusable Object-Oriented Software

by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides (The Gang of Four).

               

Abstract Factory

Adapter

Bridge

Command

Composite

Façade

Observer

Proxy

Strategy

Visitor Pattern

Visitor Intent

• Given an existing structure such as a tree or graph whose nodes are objects from different classes

• Add new behavior to the system• Without adding new operations to the classes• By encapsulating the new behavior in visitor

objects• Which traverse the structure performing tasks

when they visit the nodes

Parse Tree Visitors

• A source programming file is parsed

• A parse tree is constructed

• Its nodes represents represent productions in the grammar (~100 different classes)

• We need to add compiler functionality:– Checking, code generation, optimization

• Without modifying the node classes

Sample Parse Tree

The Solution

• Add operations to the parse tree nodes

• To support a depth-first traversal of the tree

• By an abstract Visitor object.

• The Visitor has before and after methods for each kind of node.

• Class visitor{void before(expr e){}; void after(expr e){}

Double Dispatch

• The traversal code calls the Visitor’s before method when the visitor arrives at a node, its after method before it leaves the node.

• Concrete visitors do specific tasks such as checking and code generation

• The specific before and after methods called depend on the type of the concrete visitor and the type of the node. (double dispatch)

Visiting a Train

• <Train> -> <Engine> {<Car>}* abstract class Visitor{ public Visitor(){}

public void before(Train host){}

public void after(Train host){}

public void before(Engine host){}

public void after(Engine host){}

public void before(Car host){}

public void after(Car host){}

}

A visit method in the Train class

public void visit(Visitor v){ v.before(this);

if (engine!= null) engine.visit(v);

Enumeration enumCars = getCars().elements();

while(enumCars.hasMoreElements()){

Car it = (Car) enumCars.nextElement();

it.visit(v); }

v.after(this);

}

When to use the Visitor Pattern

• When an object structure contains many classes of objects with differing interfaces and you want to perform operations on these objects that depend on their concrete classes.

• You want to encapsulate functionality in a single concrete visitor