《设计模式》一书对于访问者模式给出的定义为:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。从定义可以看出结构对象是使用访问者模式必须条件,而且这个结构对象必须存在遍历自身各个对象的方法。
设想一个场景,就是学校,学校里有老师和学生,老师和学生可以称为两种元素,我们可以对这些元素进行很多操作(注意,这些操作都是外部性质的,不属于元素本身,这个至关重要),比如评价,问卷调查,采访和体检等,如果我们把这些操作定义在元素层次,显然不合理,一是这些操作不是元素对象的固有属性和行为,而是一些外部操作,不符合面向对象的封装和责任单一原则。如果把这些操作定义在学校这层,显然也不合理,因为学校的责任只是对老师和学生进行管理,这些操作也不是学校的职责。既然不能定义在元素层和学校层,我们可以单独定义一个层次结构来实现,但这里面有两个问题,一是这些操作可能对不同的元素有不同的形式,二是这些操作还必须得到元素的许可,即元素可以接收你的访问。上面的场景其实就是访问者模式的典型应用场景,下面访问者的简图:
上面场景的实现代码:
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignModelStudy
{
public abstract class Person
{
public abstract void Accept(Person_Visitor VA);
public abstract int GetPersonType();
}
//Studeng对象.
class Student : Person
{
private int _id;
private string _name;
public override int GetPersonType()
{
return 1;
}
public Student(int ID, string Name)
{
this._name = Name;
this._id = ID;
}
public int ID
{
get
{
return this._id;
}
set
{
this._id = value;
}
}
public string Name
{
get
{
return this._name;
}
set
{
this._name = value;
}
}
public override void Accept(Person_Visitor VA)
{
System.Windows.Forms.MessageBox.Show(VA.Visit(this));
}
}
//Teacher对象.
class Teacher : Person
{
private int _id;
private string _name;
private int _age;
public Teacher(int ID, string Name,int Age)
{
this._name = Name;
this._id = ID;
this._age = Age;
}
public int ID
{
get
{
return this._id;
}
set
{
this._id = value;
}
}
public string Name
{
get
{
return this._name;
}
set
{
this._name = value;
}
}
public int Age
{
get
{
return this._age;
}
set
{
this._age = value;
}
}
public override void Accept(Person_Visitor VA)
{
System.Windows.Forms.MessageBox.Show(VA.Visit(this));
}
public override int GetPersonType()
{
return 2;
}
}
//人员管理类
class School
{
private System.Collections.ArrayList _students;
public School()
{
_students = new System.Collections.ArrayList();
}
public void Add(Person st)
{
if (this._students.IndexOf(st) < 0)
{
this._students.Add(st);
}
}
public void Del(Person st)
{
this._students.Remove(st);
}
public Person GetStudent(int index)
{
if (index >= 0 && index < this._students.Count)
{
return (Person)this._students[index];
}
return null;
}
public Person this[int index]
{
get
{
if (index >= 0 && index < this._students.Count)
{
return (Person)this._students[index];
}
return null;
}
}
public int Count
{
get
{
return this._students.Count;
}
}
}
public abstract class Person_Visitor
{
public abstract string Visit(Person p);
}
//对人员进行评价
public class EvaluateVisit : Person_Visitor
{
public override string Visit(Person p)
{
if (p is Student)
{
return "学生:" + ((Student)p).Name + " 评价" + " 结果:10";
}
else
{
return "老师:" + ((Teacher)p).Name + "" + " 年龄:" + ((Teacher)p).Age.ToString() + " 评价结果:30";
}
}
}
//对人员进行采访
public class InterviewVisit : Person_Visitor
{
public override string Visit(Person p)
{
if (p is Student)
{
return "学生:" + ((Student)p).Name + " 已经采访" + " 结果:10";
}
else
{
return "老师:" + ((Teacher)p).Name + "已经采访" + " 年龄:" + ((Teacher)p).Age.ToString();
}
}
}
public class VisitorTest
{
private School _pMgr;
public VisitorTest()
{
_pMgr = new School();
}
public void CreateDatas()
{
Random rd = new Random();
for (int i = 0; i < 10; i++)
{
if ((i % 2) == 1)
{
this._pMgr.Add(new Student(i, "学生" + i.ToString()));
}
else
{
this._pMgr.Add(new Teacher(i, "老师" + i.ToString(), 30 + Convert.ToInt32(rd.NextDouble() * 100)));
}
}
}
public void Test()
{
EvaluateVisit ev = new EvaluateVisit();
for (int i=0;i<this._pMgr.Count;i++)
{
this._pMgr[i].Accept(ev);
}
}
}
}
总结:
1)访问者模式提供了一种将数据结构和附加到该数据结构的操作进行分离解耦的方法,当然,要使用访问者模式,有一个必要条件就是数据元素要比较多而且进行集合式管理。原因非常简单,如果数据结构的元素数目比较少,而且不能进行批处理(集合的好处就是可以进行批处理),利用访问者模式就没有什么优势。
2)访问者模式适合于对那些元素数目多(而且能进行整体性管理,比如集合,组合,树型结构),需要进行附加操作(但操作多,变化大,不确定)处理的地方。
3)访问者模式一般跟集合,组合模式一起使用会比较多。
4)特别注意,访问者模式并不是为了将类的数据属性和操作属性分离。访问者模式提供的是一种数据元素与附加操作之间进行协调管理的一种方式。
后记:现在的编程语言中采用这种模式的地方很多,比如对流操作中的stream和reader,writer,针对可枚举对象的迭代和查询等。
分享到:
相关推荐
设计模式专题之(二十)访问者模式--设计模式访问者模式示例代码(python--c++)
设计模式 - 访问者模式
PPT内容包括:内附代码,实例,方便理解。 继承、封装、多态、UML 设计模式02 设计模式03-创建型模式 ...设计模式16-策略模式、模板方法、访问者 此PPT实例便于理解,对于深入理解OO思想有很大帮助。
JAVA-设计模式-行为型模式-访问者模式
设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段...
c++设计模式-行为型模式-访问者模式;qt工程;c++简单源码; 访问者(Visitor)模式的定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新...
ios 平台实现设计模式-访问者模式,以最简单的代码实现访问者模式讲解,主旨在于了解访问者模式,博客:http://blog.sina.com.cn/s/blog_161d504630102wwxe.html
设计模式-访问者模式(讲解及其实现代码)
java常用设计模式-访问者模式
设计模式C++学习之访问者模式(Visitor)
5.11 VISITOR(访问者)—对象行为型模式 218 5.12 行为模式的讨论 228 5.12 1 封装变化 228 5.12.2 对象作为参数 228 5.12.3 通信应该被封装还是被分布 229 5.12.4 对发送者和接收者解耦 229 5.12.5 总结 231 第 6 ...
访问者模式,你绝对会用到的模式,值得学习,通俗易懂的实例,原理和运用都说明白了。
java设计模式之访问者模式,通过实际例子说明访问者模式原理和适用场景;
访问者模式的简单介绍,计算机相关专业本科生,课程汇报
创建型模式,共五种:工厂方法模式、抽象工厂模式、...行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
设计模式之访问者模式Java版本的实现和UML类图
设计模式 -访问者(Visitor)模式详解和应用.pdf
最简单的访问者模式讲解代码,设计模式可看看博客中简介http://blog.sina.com.cn/s/blog_161d504630102wxis.html
【例4.5】访问者模式-计算机部件销售软件 【例4.6】命令模式-室内温度控制 【例4.7】命令模式-室内温度控制-2个GUI 【例4.8】命令模式-室内温度控制-3个GUI 【例4.10】中介者模式-旅游信息共享 ...
Visitor(访问者模式)属于行为型模式。意图:表示一个作用于某对象结构中的各元素的操作。