23种设计模式之(二十)访问者模式(Visitor)
本文主要介绍23种设计模式之访问者模式,附详细python/c++示例代码。
- 概念
- 应用场景
- 注意事项
- 代码示例
- 总结
- 代码链接
访问者模式(Visitor)
概念
在访问者模式(Visitor)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。
GoF对访问者模式的定义是:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
应用场景
(1)、对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。
(2)、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。
C++代码示例
/************************************************************************/
/* 设计模式专题
/*
/* 访问者模式
/*
/* Author : zzl
/*
/* 编程环境: window10 vs2010
/*
/* Date : 20180918
/************************************************************************/
#include <iostream>
using namespace std;
#include "list"
// Visitor ParkElement
class ParkElement;
class Visitor
{
public:
virtual void visit(ParkElement *parkelement) = 0;
};
class ParkElement
{
public:
virtual void accept(Visitor *visit) = 0;
};
class ParkA : public ParkElement
{
public:
virtual void accept(Visitor *v)
{
v->visit(this); //公园接受访问者访问 让访问者做操作
}
};
class ParkB : public ParkElement
{
public:
virtual void accept(Visitor *v)
{
v->visit(this); //公园接受访问者访问 让访问者做操作
}
};
//整个公园
class Park : public ParkElement
{
public:
Park()
{
m_list.clear();
}
void setParkElement(ParkElement *pe)
{
m_list.push_back(pe);
}
public:
virtual void accept(Visitor *v)
{
//v->visit(this); //公园接受访问者访问 让访问者做操作
for (list<ParkElement *>::iterator it = m_list.begin(); it!=m_list.end(); it++ )
{
(*it)->accept(v); //公园A 公园B 接受 管理者v访问
}
}
private:
list<ParkElement *> m_list; //公园的每一部分 //应该让公园的每一个部分 都让 管理者访问
};
class VisitorA : public Visitor
{
public:
virtual void visit(ParkElement *parkelement)
{
printf("cleaner a clear A part of the park \n");
}
};
class VisitorB : public Visitor
{
public:
virtual void visit(ParkElement *parkelement)
{
printf("cleaner b clear B part of the park \n");
}
};
class ManagerVisitor : public Visitor
{
public:
virtual void visit(ParkElement *parkelement)
{
printf("manager visit whole park \n");
}
};
void main()
{
Visitor *vA = new VisitorA;
Visitor *vB = new VisitorB;
ParkA *parkA = new ParkA;
ParkB *parkB = new ParkB;
//清洁者打扫
parkA->accept(vA);
parkB->accept(vB);
Visitor *vManager = new ManagerVisitor ;
Park *park = new Park;
park->setParkElement(parkA);
park->setParkElement(parkB);
//整个公园 接受 管理者访问
park->accept(vManager);
delete vA;
delete vB;
delete parkA;
delete parkB;
delete park;
delete vManager;
}
python代码示例
# -*- coding: utf-8 -*-
###################################################################
# 设计模式专题
#
# 访问者模式
#
# Author : zzl
#
# 编程环境: window10 python2.7
#
# Date : 20180918
##################################################################
class Visitor(object):
def visit(self, park_element):
pass
class ParkElement(object):
def accept(self, visit):
pass
class ParkA(ParkElement):
def accept(self, vister):
vister.visit(self) # 公园接受访问者访问让访问者做操作
class ParkB(ParkElement):
def accept(self, vister):
vister.visit(self) # 公园接受访问者访问让访问者做操作
# 整个公园
class Park(ParkElement):
def __init__(self):
self.m_list = []
def add_park_element(self, element):
self.m_list.append(element)
def accept(self, visitor):
for each_vistitor in self.m_list:
each_vistitor.accept(visitor) # 公园A 公园B 接受 管理者v访问
class VisitorA(Visitor):
def visit(self, park_element):
print("cleaner a clear A part of the park")
class VisitorB(Visitor):
def visit(self, park_element):
print("cleaner b clear B part of the park")
class ManagerVisitor(Visitor):
def visit(self, park_element):
print("manager visit whole park")
if __name__ == "__main__":
visitorA = VisitorA()
visitorB = VisitorB()
parkA = ParkA()
parkB = ParkB()
# 清洁者打扫
parkA.accept(visitorA)
parkB.accept(visitorB)
vManager = ManagerVisitor()
park = Park()
park.add_park_element(parkA)
park.add_park_element(parkB)
# 整个公园接受管理者访问
park.accept(vManager)