设计模式读书笔记:Visitor(访问者)
2015-07-10 21:55:55
意图:
表示一个作用于某对像结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
结构图:截屏于原著
实现:https://github.com/panshiqu/patterns/tree/master/Visitor
Visitor
namespace NS_VISITOR {
class ConcreteElementA;
class ConcreteElementB;
class Visitor {
public:
Visitor() {}
virtual ~Visitor() {}
virtual void visitConcreteElementA(ConcreteElementA *cea) = 0;
virtual void visitConcreteElementB(ConcreteElementB *ceb) = 0;
};
} /* namespace NS_VISITOR */
ConcreteVisitor1
#include "Visitor.h"
#include "ConcreteElementA.h"
#include "ConcreteElementB.h"
namespace NS_VISITOR {
class ConcreteVisitor1 : public Visitor
{
public:
ConcreteVisitor1() : _total(0) {}
virtual ~ConcreteVisitor1() {}
virtual void visitConcreteElementA(ConcreteElementA *cea)
{
if (cea->getType())
_total += cea->getPrice();
}
virtual void visitConcreteElementB(ConcreteElementB *ceb)
{
if (ceb->getType())
_total += ceb->getPrice();
}
int getTotal(void) { return _total; }
private:
int _total;
};
} /* namespace NS_VISITOR */
ConcreteVisitor2
#include "Visitor.h"
#include "ConcreteElementA.h"
#include "ConcreteElementB.h"
namespace NS_VISITOR {
class ConcreteVisitor2 : public Visitor
{
public:
ConcreteVisitor2() : _total(0) {}
virtual ~ConcreteVisitor2() {}
virtual void visitConcreteElementA(ConcreteElementA *cea)
{
_total += cea->getPrice();
}
virtual void visitConcreteElementB(ConcreteElementB *ceb)
{
_total += ceb->getPrice();
}
int getTotal(void) { return _total; }
private:
int _total;
};
} /* namespace NS_VISITOR */
Element
namespace NS_VISITOR {
class Visitor;
class Element {
public:
enum ELEMENT_TYPE {
COMMON,
SPECIAL,
};
Element(int type, int price) : _type(type), _price(price) {}
virtual ~Element() {}
virtual void accept(Visitor *visitor) = 0;
int getType(void) { return _type; }
int getPrice(void) { return _price; }
private:
int _type;
int _price;
};
} /* namespace NS_VISITOR */
ConcreteElementA
#include "Visitor.h"
#include "Element.h"
namespace NS_VISITOR {
class Visitor;
class ConcreteElementA : public Element
{
public:
ConcreteElementA(int type, int price) : Element(type, price) {}
virtual ~ConcreteElementA() {}
virtual void accept(Visitor *visitor)
{
visitor->visitConcreteElementA(this);
}
};
} /* namespace NS_VISITOR */
ConcreteElementB
#include "Visitor.h"
#include "Element.h"
namespace NS_VISITOR {
class Visitor;
class ConcreteElementB : public Element
{
public:
ConcreteElementB(int type, int price) : Element(type, price) {}
virtual ~ConcreteElementB() {}
virtual void accept(Visitor *visitor)
{
visitor->visitConcreteElementB(this);
}
};
} /* namespace NS_VISITOR */
main
#include <list>
#include <iostream>
#include "Visitor/ConcreteVisitor1.h"
#include "Visitor/ConcreteVisitor2.h"
#include "Visitor/ConcreteElementA.h"
#include "Visitor/ConcreteElementB.h"
using namespace NS_VISITOR;
using namespace std;
int main(void)
{
list<Element *> elements;
ConcreteElementA cea(Element::COMMON, 100);
elements.push_back(&cea);
ConcreteElementB ceb(Element::SPECIAL, 100);
elements.push_back(&ceb);
ConcreteVisitor1 cv1;
list<Element *>::iterator itr1 = elements.begin();
for (; itr1 != elements.end(); itr1++)
(*itr1)->accept(&cv1);
std::cout << "Special: " << cv1.getTotal() << std::endl;
ConcreteVisitor2 cv2;
list<Element *>::iterator itr2 = elements.begin();
for (; itr2 != elements.end(); itr2++)
(*itr2)->accept(&cv2);
std::cout << "All: " << cv2.getTotal() << std::endl;
}
附加: