[设计模式笔记]三. 行为型模式--25. Visitor模式(访问者)对象行为型模式(二)

场景


根据Visitor模式的结构图和自己的理解.


如图:



图1

代码

class ObjectStruct
{
public:
	Element* m_pElementA;
	Element* m_pElementB;
	// 你也可以使用一个数组, 列表等来存储里面的ObjectStruct中的元素.
	// 因为这里使用的是父类Element的指针, 所以你在使用
	// Visitor::VisitConcreteElementA和Visitor::VisitConcreteElementB传入的参数必须是正确的参数类型
};
//

class Visitor
{
public:
	...
	vritual void VisitConcreteElementA(ConcreteElementA* pConcreteElementA);
	vritual void VisitConcreteElementB(ConcreteElementB* pConcreteElementB);
	// 有objectStruct中多少个具体Element, 就需要多少个VisitConcreteElement函数.
};
//
class ConcreteVisitor1 : public Visitor
{
public:
	...
	vritual void VisitConcreteElementA(ConcreteElementA* pConcreteElementA);
	vritual void VisitConcreteElementB(ConcreteElementB* pConcreteElementB);
	// 有objectStruct中多少个具体Element, 就需要多少个VisitConcreteElement函数.
};
...
void ConcreteVisitor1::VisitConcreteElementA(ConcreteElementA* pConcreteElementA)
{
	...
	pConcreteElementA->OperationA();
	...
}

void ConcreteVisitor1::VisitConcreteElementB(ConcreteElementB* pConcreteElementB)
{
	...
	...
	pConcreteElementB->OperationB();
	...
}
//
class ConcreteVisitor2 : public Visitor
{
public:
	...
	vritual void VisitConcreteElementA(ConcreteElementA* pConcreteElementA);
	vritual void VisitConcreteElementB(ConcreteElementB* pConcreteElementB);
	// 有objectStruct中多少个具体Element, 就需要多少个VisitConcreteElement函数.
};
...
void ConcreteVisitor2::VisitConcreteElementA(ConcreteElementA* pConcreteElementA)
{
	pConcreteElementA->OperationA();
	......
	......
}

void ConcreteVisitor2::VisitConcreteElementB(ConcreteElementB* pConcreteElementB)
{
	...
	...
	...
	pConcreteElementB->OperationB();
}
//
class Element
{
public:
	...
	vritual void Accept(Visitor* pVisitor) = 0;
};
//
class ConcreteElementA : public Element
{
public:
	...
	vritual void Accept(Visitor* pVisitor) ;
	void OperationA();	// 一些操作, 可以供其他类调用, 例如Visitor
};

// 这里是理解关键
void ConcreteElementA ::Accept(Visitor* pVisitor)
{
	pVisitor->VisitConcreteElementA(this);
}

//
class ConcreteElementB : public Element
{
public:
	...
	vritual void Accept(Visitor* pVisitor);
	void OperationB();	// 一些操作, 可以供其他类调用, 例如Visitor
};
// 这里是理解关键
void ConcreteElementB ::Accept(Visitor* pVisitor)
{
	pVisitor->VisitConcreteElementB(this);
}


// Client 调用
// 1. 构建ObjectStruct对象(这里的构建过程应该与Visitor模式无关的, 根据自己需求来构建)
ObjectStruct* pObjectStruct = new ObjectStruct;
pObjectStruct->m_pElementA = new ConcreteElementA;
pObjectStruct->m_pElementB= new ConcreteElementB;

// 2. 使用访问者来操作 
ConcreteVisitor1* pConcreteVisitor1 = new ConcreteVisitor1;
pObjectStruct->m_pElementA->Accept(pConcreteVisitor1 );
ConcreteVisitor2* pConcreteVisitor1 = new ConcreteVisitor2;
pObjectStruct->m_pElementA->Accept(pConcreteVisitor2 );
pObjectStruct->m_pElementB->Accept(pConcreteVisitor1 );


// 看协作图



我的理解


1. ObjectStruct与具体Visitor是解耦的, ObjectStruct可以不需要知道具体的Visitor, 它通过Element::Accept(Visitor* pVisitor)来操作具体Element


2. 假设不使用Visitor模式如果增加Element的操作则你需要修改对应的具体Element, 这样修改的话, ObjectStruct也对应的被间接修改了而如果使用Visitor模式则只需要增加一个具体Visitor类和在调用的地方修改即可.


3. 增加具体Visitor简答方便ObjectStruct增加一个Element, Visitor层次需要改变Visitor的接口例如增加一个ElementC, Visitor类需要增加操作ElementC的接口抽象父类增加了接口它的所有子类也要增加. (笛卡尔积)


4. Visitor模式的这种增加一个具体Element时需要对Visitor的接口改变的问题与Abstract Factory模式有点相似就是在Abstract Factory模式中如果需要增加一个产品AbstractProductC, 你需要在AbstractFactory类上增加一个创建新AbstractProductC的接口从而所有的具体Factory也要实现这个接口.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值