Outline • Generic Implementation • UML Design – Visitor classes

advertisement
Outline
• Generic Implementation
– Visitor classes
– Visited classes
– Visitable macro
• UML Design
– Use cases
– Class diagram
– Sequence diagram
7/1/2016
CS 631: Visitor Implementation
1
The Generic Implementation
• BaseVisitable
– The root of all hierarchies that can be visited
• Visitable
– A mix-in class that converts visitable properties to a class in
visitable hierarchy
• BaseVisitor
– The root of the visitor hierarchy
• Visitor
– A mix-in class that confers visitor properties to a class in the
visitor hierarchy
7/1/2016
CS 631: Visitor Implementation
2
Generic Implementation: Visitor Classes
// The strawman class
class BaseVisitor
{
public:
virtual ~TraderVisitor() {}
};
// Class to define a pure virtual function for
// visiting an object of type T and return type R
template <class T, typename R = void>
class Visitor
{
public:
typedef R ReturnType
virtual ReturnType visit(T&) = 0;
}
7/1/2016
CS 631: Visitor Implementation
3
Generic Implementation: Concrete Visitor
class DealEvaluator :
public class BaseVisitor, // required
public class Visitor<Hedger>,
public class Visitor<Speculator>,
public class Visitor<Arbitrageur>
{
public:
void visit(Hedger &);
void visit(Speculator&);
void visit(Arbitrageur&);
};
7/1/2016
CS 631: Visitor Implementation
4
Generic Implementation: Base Visited
Class
// The base visitable class to define accept()
template <typename R=void>
class BaseVisitable
{
public:
typedef R ReturnType;
virtual ~BaseVisitable() {}
virtual ReturnType accept(BaseVisitor&) = 0;
};
// The challenge is to provide a library
// implementation for concrete accept() functions
7/1/2016
CS 631: Visitor Implementation
5
Generic Implementation: Visitable Macro
#define DEFINE_VISITABLE() \
virtual ReturnType accept(BaseVisitor& guest) \
{return acceptImpl(*this, guest);}
template <typename R=void>
class BaseVisitable
{
public:
...
typedef R ReturnType;
virtual ~BaseVisitable() {}
virtual ReturnType accept(BaseVisitor&) = 0;
7/1/2016
CS 631: Visitor Implementation
6
Generic Implementation: Visitable Macro
(cont.)
// class BaseVisitable
...
protected: // Give access only to hierarchy
...
template <class T>
static ReturnType acceptImpl
(T& visited, BaseVisitor& guest)
{
// Acyclic visitor
if (Visitor<T>* p = dynamic_cast<Visitor<T>*
(&guest))
return p->visit(visited);
return ReturnType();
}
7/1/2016
CS 631: Visitor Implementation
7
Generic Implementation: Concrete Visited
Classes
class Trader : public class BaseVisitable<>
{
public:
DEFINE_VISITABLE()
...
};
class Hedger : public class Trader
{
public:
DEFINE_VISITABLE()
...
}
7/1/2016
CS 631: Visitor Implementation
8
Generic Implementation: Concrete Visited
Classes
class DealEvaluator :
public class BaseVisitor, // required
public class Visitor<Trader>, // visits Trader
public class Visitor<Hedger>, // visits Hedger
...
{
public:
void visit(Trader&) {...}
void visit(Hedger&) {...}
...
};
int main()
{
DealEvaluator eval;
Trader trader = new Hedger();
trader->accept(eval);
}
7/1/2016
CS 631: Visitor Implementation
9
Generic Implementation: Summary
• Derive the root of your hierarchy from
BaseVisitable<YourReturnType>
• Add to each class (Trader, Hedger) in the visitable
hierarchy the DEFINE_VISITABLE macro.
– The hierarchy is ready to be visited with no dependency on
any Visitor class!
• Derive each concrete Visitor (TraderVisitor,
DealMaker, ...) from BaseVisitor. Also derive it from
all concrete visitable classes X:
Visitor<X,YourReturnType>
• The client code and dependencies are reduced to the
bare necessity.
7/1/2016
CS 631: Visitor Implementation
10
Market Simulator: Use Case Diagram
7/1/2016
CS 631: Visitor Implementation
11
Visitor Pattern: Class Diagram
7/1/2016
CS 631: Visitor Implementation
12
Visitor Pattern: Sequence Diagram
7/1/2016
CS 631: Visitor Implementation
13
Visitor Pattern: Summary
• Visitor makes adding new operation easy.
– Adding a new operation means adding a new visitor.
• A visitor gathers related operations and separates
unrelated ones.
– Related behavior is localized in a visitor.
– Unrelated sets of behavior are partitioned in their own visitor
subclasses.
• Adding new ConcreteElement classes is hard.
– Each new class results in adding methods to the Visitor
hierarchy.
– Element hierarchy needs to be stable!
7/1/2016
CS 631: Visitor Implementation
14
Summary (cont.)
• Visiting across class hierarchies.
– Any type of object can be added to a Visitor interface:
• visitMyType(MyType&); visitYourType(YourType&)
• Accumulating state.
– Visitors can accumulate state as they visit each element in
the object structure.
• Breaking encapsulation.
– Assumes the ConcreteElement interface is powerful enough
to let visitors do their job.
– The pattern often forces to expose more public interface.
7/1/2016
CS 631: Visitor Implementation
15
Download