编程模式之访问者
2021/12/24 20:09:57
本文主要是介绍编程模式之访问者,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
访问者模式,个人理解为是一个分类器,可以把抽象类型恢复到具体类型。面向对象的子类父类就是为了解决抽象、具体的问题。抽象的接口不好定义,免不了少定义了,又要改接口,而有些接口可能还不是很适用于每个具现类,这个时候是要定义抽象接口还是不需要呢,程序员又得费脑细胞了。访问者模式可以方便的将抽象类型落实到具体类型对象。也就是说,你给我一个箱子说装着一个动物,让我给准备食物,通过访问者模式就知道了它原来是一个狗狗,那就准备骨头吧。而且随时可以组织一个喂食访问者、或者一个防疫访问者,不用去修改动物这个类型的接口。这个模式也是实际使用最多的模式之一。
一般来说访问者模式要有一个Element抽象类,定义被访问者的基础方法Accept。一个访问者基类Visitor,定义了所有Element的具现类的访问接口。所以一般来说要求Eelement的具现类要稳定,否则,Visitor接口要反复修改就不太妙了。而且如果有些具体Visitor只处理一部分Element种类的情况也麻烦,还说上面的动物,如果一个具体的Visitor要看一个动物是否是鸡,如果是鸡就打预防针,否则不管。就这样的一个功能,还要处理其他各种动物的接口就不美了。
下面介绍本人实现的访问者模式,可以灵活组织,避免不少麻烦,经过多年的应用,基本没有修改过。
//所有Visitor的基类
//让所有的Visitor有一个统一的接口
class Base_Visitor
{
public:
virtual ~Base_Visitor(){};
};
//对每个具体的Visitee进行访问的基类
template<class T,typename R>
class Visitor
{
public:
virtual ~Visitor(){};
typedef R ReturnType;
public:
//对Visitee对象的访问和扩展
virtual ReturnType Visit(T&) = 0;
};
template<typename R = void>
class Visitee
{
public:
virtual ~Visitee(){};
typedef R ReturnType;
public:
//和宏DEFINE_Visitee配合把具体Visitee和visitor建立关联
virtual ReturnType Accept(Base_Visitor& visitor) = 0;
protected:
//静态函数,目的是为了visitor能访问具体的Visitee对象
//也是和DEFINE_Visitee配合,对具体的Visitee对象T进行访问注册
template<class T>
static ReturnType AcceptImpl(T& visitee, Base_Visitor& guest)
{
Visitor<T, ReturnType>* p = dynamic_cast<Visitor<T, ReturnType>*>(&guest);
//把具体的Visitee注册到对应的Visitor中
//Visitor由BaseVisitor派生,并且以具体的Visitee类为模板参数
if(NULL != p)
{
return p->Visit(visitee);
}
return ReturnType();
}
};
#define DEFINE_VISITEE() \
public: \
virtual ReturnType Accept(Base_Visitor& visitor) \
{ return AcceptImpl(*this, visitor); }
应用示例:
class A : public Visitee<bool>
{
DEFINE_VISITEE()
}
class B : public Visitee<bool>
{
DEFINE_VISITEE()
}
Class C : public Visitee<bool>
{
DEFINE_VISITEE()
}
class ABVisitor : public Base_Visitor,public Visitor<A,bool>,public Visitor<B,bool>
{
virtual bool Visit(A& obj)
{
//do somthing
return true;
}
virtual bool Visit(B& obj)
{
return true;
}
}
C cObj;
ABVisitor v;
bool b = cObj.Accept(v);//b == false;
B bObj;
b = bObj.Accept(v);//b == true;
如例:Visitor可以随时组织,可以对被访问者的一部分进行访问操作,也可以对全体进行访问操作。新写的代码不影响以前的代码,即使多了对象D,如果非逻辑需求,以前写的Visitor也可以不处理。
比如做一个图形系统:
圆、矩形、多边形、扇形、直线、折线都继承自Visitee。将一张图中的所有对象序列化,就可以用一个Visitor,将一张图所有对象写成XML格式文件可以用另一个Visitor,可以有一个Visitor给所有有面积的设置填充颜色。当鼠标选中一个图形对象的时候,可以用一个Visitor给这个选中对象分配对应的编辑对象来处理鼠标键盘事件。总之,需要针对不同对象处理什么事情的时候就可以写一个Visitor,很方便扩展。不用修改以前的代码,非常符合模式的基本原则。
访问者模式可以和消息树结合应用,减少消息树不必要的动态类型转换,也就是利用访问者模式,将消息具体到具体消息,再进行具体操作,读者可以先自行考虑,应该是水到渠成。笔者有时间再写吧。
这篇关于编程模式之访问者的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南