一.访问者模式的定义:

表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。

二.访问者模式的结构和角色:

1.Visitor 抽象访问者角色,为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色,这样访问者就可以通过该元素角色的特定接口直接访问它。
2.ConcreteVisitor.具体访问者角色,实现Visitor声明的接口。
3.Element 定义一个接受访问操作(accept()),它以一个访问者(Visitor)作为参数。
4.ConcreteElement 具体元素,实现了抽象元素(Element)所定义的接受操作接口。
5.ObjectStructure 结构对象角色,这是使用访问者模式必备的角色。它具备以下特性:能枚举它的元素;可以提供一个高层接口以允许访问者访问它的元素;如有需要,可以设计成一个复合对象或者一个聚集(如一个列表或无序集合)。

三.访问者模式的实现:

在生活中,我们要去医院看病,当我们挂号找到主治医生的医生看完病以后,会给你开一张药单,这个时候你需要先去付费,由划价医生收取药费,然后你拿着付费单再去找抓药师抓药。传统上我们也许会,写一个划价师类,里面根据药的名称做判断收取多少费用;写一个抓药师根据药单上面名称要判断去哪里抓药。可能使用Switch进行判断,这样增加了药就要改变划价人员和药房工作者的代码。

访问者模式的目的是封装一些施加于某种数据结构元素之上的操作,一旦这些操作需要修改的话,接受这个操作的数据结构可以保持不变。为不同类型的元素提供多种访问操作方式,且可以在不修改原有系统的情况下增加新的操作方式,这就是访问者模式的模式动机。

/// <summary>
/// 抽象访问者
/// </summary>
public abstract class Visitor
{
protected string name { get; set; } public Visitor(string name)
{
this.name = name;
} public abstract void visitor(MedicineA a); public abstract void visitor(MedicineB b);
} // 何问起 hovertree.com
/// <summary>
/// 具体访问者:划价员
/// </summary>
public class Charger :Visitor
{
public Charger(string name) : base(name) { } public override void visitor(MedicineA a)
{
Console.WriteLine("划价员:"+this.name+"给药"+a.GetName()+"价格:"+a.GetPrice());
} public override void visitor(MedicineB b)
{
Console.WriteLine("划价员:" + this.name + "给药" + b.GetName() + "价格:" + b.GetPrice());
}
} // 何问起 hovertree.com
/// <summary>
/// 具体访问者:药房工作者
/// </summary>
public class WorkerOfPharmacy:Visitor
{
public WorkerOfPharmacy(string name) : base(name) { }
public override void visitor(MedicineA a)
{
Console.WriteLine("药房工作者:"+this.name+",拿药:"+a.GetName());
} public override void visitor(MedicineB b)
{
Console.WriteLine("药房工作者:" + this.name + ",拿药:" + b.GetName());
}
} // 何问起 hovertree.com
/// <summary>
/// 抽象元素:药
/// </summary>
public abstract class Medicine
{
protected string name { get; set; }
protected double price { get; set; } public Medicine(string name, double price)
{
this.name = name;
this.price = price;
} public string GetName()
{
return name;
} public double GetPrice()
{
return price;
} public void SetPrice(double price)
{
this.price = price;
} public abstract void accept(Visitor visitor);
} // 何问起 hovertree.com
/// <summary>
/// 具体元素:A名称药
/// </summary>
public class MedicineA:Medicine
{
public MedicineA(string name, double price) : base(name, price) { } public override void accept(Visitor visitor)
{
visitor.visitor(this);
}
} // 何问起 hovertree.com
/// <summary>
/// 具体元素:B名称药
/// </summary>
public class MedicineB:Medicine
{
public MedicineB(string name, double price) : base(name, price) { } public override void accept(Visitor visitor)
{
visitor.visitor(this);
}
} // 何问起 hovertree.com
/// <summary>
/// 具体元素:药单
/// </summary>
public class Presciption
{
private List<Medicine> listmedicine = new List<Medicine>();
public void accpet(Visitor visitor)
{
foreach (var item in listmedicine)
{
item.accept(visitor);
}
} public void add(Medicine med)
{
listmedicine.Add(med);
} public void remove(Medicine med)
{
listmedicine.Remove(med);
}
} // 何问起 hovertree.com
/// <summary>
/// C#设计模式-访问者模式
/// </summary>
class Program
{
static void Main(string[] args)
{
//药类型
Medicine a = new MedicineA("药A", );
MedicineB b = new MedicineB("药B", ); //药单
Presciption presciption = new Presciption();
presciption.add(a);
presciption.add(b); Visitor charger = new Charger("张三"); //划价员
Visitor workerOfPharmacy = new WorkerOfPharmacy("李四"); //抓药员 presciption.accpet(charger); //划价
Console.WriteLine();
presciption.accpet(workerOfPharmacy); //抓药
}
} // 何问起 hovertree.com

四.访问者模式优缺点:

优点:
1、使得新增新的访问操作变得更加简单。
2、能够使得用户在不修改现有类的层次结构下,定义该类层次结构的操作。
3、将有关元素对象的访问行为集中到一个访问者对象中,而不是分散搞一个个的元素类中。
缺点:
1、增加新的元素类很困难。在访问者模式中,每增加一个新的元素类都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中增加相应的具体操作,违背了“开闭原则”的要求。
2、破坏封装。当采用访问者模式的时候,就会打破组合类的封装。
3、比较难理解

五.使用场景:

1、对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。
2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类。

http://www.cnblogs.com/roucheng/p/3521864.html

.NET设计模式访问者模式的更多相关文章

  1. C#设计模式-访问者模式

    一. 访问者(Vistor)模式 访问者模式是封装一些施加于某种数据结构之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保存不变.访问者模式适用于数据结构相对稳定的系统, 它把数据结 ...

  2. JAVA 设计模式 访问者模式

    用途 访问者模式 (Visitor) 表示一个作用于某对象结构中的各元素的操作. 它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 访问者模式是一种行为型模式. 用途

  3. 深入浅出设计模式——访问者模式(Visitor Pattern)

    模式动机 对于系统中的某些对象,它们存储在同一个集合中,且具有不同的类型,而且对于该集合中的对象,可以接受一类称为访问者的对象来访问,而且不同的访问者其访问方式有所不同,访问者模式为解决这类问题而诞生 ...

  4. java设计模式---访问者模式

      Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自 己对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广 泛,遵循一定的编程模式,才能使自 ...

  5. C++设计模式——访问者模式

    访问者模式 在GOF的<设计模式:可复用面向对象软件的基础>一书中对访问者模式是这样说的:表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的 ...

  6. 设计模式 -- 访问者模式(Visitor)

    写在前面的话:读书破万卷,编码如有神--------------------------------------------------------------------主要内容包括: 初识访问者模 ...

  7. Java设计模式—访问者模式

    原文地址:http://www.cnblogs.com/java-my-life/archive/2012/06/14/2545381.html 总结的太棒啦,导致自己看了都不想总结了...... 在 ...

  8. C#设计模式——访问者模式(Visitor Pattern)

    一.概述由于需求的改变,某些类常常需要增加新的功能,但由于种种原因这些类层次必须保持稳定,不允许开发人员随意修改.对此,访问者模式可以在不更改类层次结构的前提下透明的为各个类动态添加新的功能.二.访问 ...

  9. Java设计模式-访问者模式(Visitor)

    访问者模式把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化.访问者模式适用于数据结构相对稳定算法又易变化的系统.因为访问者模式使得算法操作增加变得容易.若系统数据结构对象易于变化,经 ...

随机推荐

  1. 构建一个基本的前端自动化开发环境 —— 基于 Gulp 的前端集成解决方案(四)

    通过前面几节的准备工作,对于 npm / node / gulp 应该已经有了基本的认识,本节主要介绍如何构建一个基本的前端自动化开发环境. 下面将逐步构建一个可以自动编译 sass 文件.压缩 ja ...

  2. 【腾讯bugly干货分享】HTML 5 视频直播一站式扫盲

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=1277 视频直 ...

  3. ASP.NET内置对象的总结

    1. Response对象可形象的称之为响应对象,用于将数据从服务器发送回浏览器. 实例源码:链接: http://pan.baidu.com/s/1dDCKQ8x 密码: ihq0  2. Requ ...

  4. DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(3)

    上一篇:<DDD 领域驱动设计-谈谈 Repository.IUnitOfWork 和 IDbContext 的实践(2)> 这篇文章主要是对 DDD.Sample 框架增加 Transa ...

  5. dotNet Core开发环境搭建及简要说明

    一.安装 .NET Core SDK 在 Windows 上使用 .NET Core 的最佳途径:使用Visual Studio. 免费下载地址: Visual Studio Community 20 ...

  6. 真假4K电视验证:一张图足矣

    国庆期间笔者逛了一下电视卖场,考虑到国内电视台以及宽带的情况,1080P至少还能用十年,所以只想要个2k电视就够了.然而事与愿违,卖场中八成的都是4k电视,清一色的4k电视让人眼花缭乱.难道4k面板技 ...

  7. servlet 简介,待完善

    什么是Servlet?① Servlet就是JAVA 类② Servlet是一个继承HttpServlet类的类③ 这个在服务器端运行,用以处理客户端的请求 Servlet相关包的介绍--javax. ...

  8. Android 添加ActionBar Buttons

    一.在res/menu文件夹下创建Xml文件 跟标签为menu,设置item <?xml version="1.0" encoding="utf-8"?& ...

  9. Git(1)

    安装Git 完毕 (在开始菜单打开的话,打开的不是你想要的路径,切换路径很麻烦) 1.D盘新建 GitTest 文件夹 2.打开GitTest , 在空白的地方右键, 3.单击 Git Bash He ...

  10. JavaScript中的this

    本文尽量避免概念性的讲解,那样太抽象 所以下面以一些简单的例子,从易到难对this的用法总结 1.方法中的this会指向当前执行该方法的对象 如: var name = "window&qu ...