设计模式—访问者模式(二十三)

        软件领域中的设计模式的重要性不言而喻。设计模式中运用了面向对象编程语言的重要特性:封装、继承、多态。虽然知道这些特性的定义但是并没有做到真正的理解,这样特性有什么作用?用于什么场合中等等问题,带着疑问开始学习设计模式,主要参考《大话设计模式》和《设计模式:可复用面向对象软件的基础》两本书。

        访问者模式(Visitor):封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。

        访问者模式的目的是要把处理从数据结构分离出来。有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式就是比较合适的,因为访问者模式使得算法操作的增加变得容易。

        优点:仿问者模式的优点就是增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者。访问者模式将有关的行为集中到一个访问者对象中。

        缺点:使增加新的数据结构变得困难了。


        Visitor ——抽象访问者

抽象类或者接口,声明访问者可以访问哪些元素,具体到程序汇中就是visit方法的参数定义哪些对象是可以被访问的。

        ConcreteVisitor——具体访问者

它影响访问者访问到一个类后该怎么干,要做什么事情。

        Element——抽象元素

接口或抽象类,声明接受哪一类访问者访问,程序上是通过accept方法中的参数来定义的。

        ConcreteElement——具体元素

实现accept方法,通常是visitor.visit(this),基本上都形成了一种模式了。

        ObjectStruture——结构对象

元素生产者,一般容纳在多个不同类、不同接口的容器。

        访问者模式其实主要就是让接口Element及其实现子类负责数据结构的定义,而关于这些数据的操作,则放在访问者类中,每个访问者子类可以负责实现一系列相关的涉及不同数据子结构(Element子类型)的操作,而不同的访问者子类可以定义完全不相关的操作。也就是说访问者模式的主要作用是把数据结构和作用于结构上的操作解耦合,使得操作集合可以相对自由地演化。这样访问者模式的优点就是增加新的操作容易,因为增加新的操作就意味着增加一个新的访问者;而访问者模式的缺点就是增加新的数据结构比较困难。综上,如果系统有比较稳定的数据结构,又有已于变化的算法的话,使用访问者模式就比较合适。


例:

#include <iostream>    
#include <vector>
#include <string>    
using namespace std;
class Woman;
class Man;
//抽象行动(抽象观察者)
class Action{
public:
	virtual void GetManConclusion(Man* concreteElementA) = 0;
	virtual void GetWomanConclusion(Woman* concreteElementB) = 0;	
};
//抽象人类
class Persion{
public:
	virtual void Accept(Action* visitor) = 0;
};
//具体人1 (具体元素1)
class Man :public Persion
{
	virtual void Accept(Action* visitor)
	{
		visitor->GetManConclusion(this);
	}
};
//具体人2 (具体元素2)
class Woman :public Persion
{
	virtual void Accept(Action* visitor)
	{
		visitor->GetWomanConclusion(this);
	}
};
//具体访问者1
class Success :public Action
{
	virtual void GetManConclusion(Man* concreteElementA)
	{
		cout << "成功男人的背后有一个伟大的女人" << endl;
	}
	virtual void GetWomanConclusion(Woman* concreteElementB)
	{
		cout << "成功女人的背后有一个不成功的男人" << endl;
	}
};
//具体访问者2
class Failure :public Action
{
	virtual void GetManConclusion(Man* concreteElementA)
	{
		cout << "男人失败,闷头喝酒" << endl;
	}
	virtual void GetWomanConclusion(Woman* concreteElementB)
	{
		cout << "女人失败,两眼汪汪" << endl;
	}
};
//对象结构类
class ObjectStructure{
private:
	vector<Persion*> elements;
public:
	void AddElement(Persion* element)
	{
		elements.push_back(element);
	}
	void Display(Action* visitor)
	{
		for (Persion* a : elements)
			a->Accept(visitor);
	}
};

int main()
{
	ObjectStructure* o = new ObjectStructure();
	o->AddElement(new Man());
	o->AddElement(new Woman());

	Success* v1 = new Success();
	o->Display(v1);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值