模式简介

当一个类的结构不再发生改变,但是我们需要从类的外部动态实现或改变该类里面的一些方法时,我们就需要用到访客模式。

模式UML图

代码示例(C#)

提示:可在本栏目的资源篇“设计模式代码示例合集”下载所有完整代码资源。

    //公寓,房屋类型之一public class Apartment : House{public Apartment(string p_name, HousePart p_kitchen, HousePart p_toilet, HousePart p_bedroom) :base(p_name, p_kitchen, p_toilet, p_bedroom){ }public override IVisitor Accept(IVisitor p_visitor){WelcomeAndInstructions();p_visitor.Visit();return p_visitor;}protected override void WelcomeAndInstructions(){Console.WriteLine("Welcome to my " + name + ".");kitchen.Do();bedroom.Do();toilet.Do();}}//别墅,房屋类型之一public class Villa : House{public Villa(string p_name, HousePart p_kitchen, HousePart p_toilet, HousePart p_bedroom) :base(p_name, p_kitchen, p_toilet, p_bedroom){ }public override IVisitor Accept(IVisitor p_visitor){WelcomeAndInstructions();p_visitor.Visit();return p_visitor;}protected override void WelcomeAndInstructions(){Console.WriteLine("Welcome to my " + name + ".");kitchen.Do();bedroom.Do();toilet.Do();}}//厨房,房屋结构之一public class Kitchen : HousePart{public Kitchen(string p_name) : base(p_name) { }public override void Do(){Console.WriteLine("Welcome to " + name + ".This is a place for cooking.");}}//厕所,房屋结构之一public class Toilet : HousePart{public Toilet(string p_name) : base(p_name) { }public override void Do(){Console.WriteLine("Welcome to " + name + ".This is a place to return to nature.");}}//卧室,房屋结构之一public class Bedroom : HousePart{public Bedroom(string p_name) : base(p_name) { }public override void Do(){Console.WriteLine("Welcome to " + name + ".This is a place to sleep.");}}//儿童,访客类型之一public class Child : IVisitor{public void Visit(){VisitBedroom();VisitKitchen();VisitToilet();}public void VisitBedroom(){Console.WriteLine("The child plays in the bedroom");}public void VisitEnd(){Console.WriteLine("-----------------------------------");}public void VisitKitchen(){Console.WriteLine("The child feels hungry,so he wants to find some foods to eat in the kitchen.");}public void VisitToilet(){Console.WriteLine("Beacuse of drinking much juice,the child wants to return to nature.");}}//女士,访客类型之一public class Woman : IVisitor{public void Visit(){VisitToilet();VisitBedroom();VisitKitchen();}public void VisitEnd(){Console.WriteLine("-----------------------------------");}public void VisitBedroom(){Console.WriteLine("The woman feels sleepy so that she is fast asleep in the bedroom.");}public void VisitKitchen(){Console.WriteLine("The woman feels a little hungry after a sleep and she find some cookies in the refrigerator of kitchen luckily.");}public void VisitToilet(){Console.WriteLine("The woman wants to return to nature beacuse of drinking much wine last night.");}}//访客接口,所有访客实现该接口public interface IVisitor{public void VisitKitchen();public void VisitToilet();public void VisitBedroom();public void Visit();public void VisitEnd();}//房屋基类,所有房屋继承该基类public abstract class House{protected string name;protected HousePart kitchen;protected HousePart toilet;protected HousePart bedroom;public House(string p_name, HousePart p_kitchen, HousePart p_toilet, HousePart p_bedroom){name = p_name;kitchen = p_kitchen;toilet = p_toilet;bedroom = p_bedroom;}protected abstract void WelcomeAndInstructions();public abstract IVisitor Accept(IVisitor p_visitor);}//房屋结构基类,所有房屋结构继承该基类public abstract class HousePart{public string name;public HousePart(string p_name) { name = p_name; }public abstract void Do();}//测试代码public void Test(){Kitchen kitchen = new Kitchen("kitchen");Toilet toilet = new Toilet("toilet");Bedroom bedroom = new Bedroom("bedroom");Apartment apartment = new Apartment("apartment", kitchen, toilet, bedroom);Villa villa = new Villa("villa", kitchen, toilet, bedroom);Child child = new Child();Woman woman = new Woman();apartment.Accept(child).VisitEnd();apartment.Accept(woman).VisitEnd();villa.Accept(child).VisitEnd();villa.Accept(woman).VisitEnd();}

代码解说

我们这里的示例就是不同访客来游览不同的房屋,每个房屋都需要继承House基类,其中WelcomeAndInstructions方法用于介绍这是什么类型的房屋以及房屋中的各个房间用来做什么,Accept方法用于接待访客,房屋的结构一旦确定就不会再进行改变了,但是如果我们不采用访客模式,那么接待不同的访客我们都需要通过修改或添加房屋中的接待方法,这就违背了开闭原则,如果我们把这个接待方法改为访问方法,我们规定每个访客都需要一个Visit方法,以及与房屋结构相适应的VisitKitchen、VisitToilet、VisitBedroom等方法,作为房屋就只需要直接调用参观的访客的Visit方法即可,毕竟访客要怎么参观是访客要做的事情,我们交给访客自己去定义就行了,房屋只需要知道访客是否要参观即可,有一个问题就是,为什么我这里需要添加一个Visit方法,原则上只需要VisitKitchen、VisitToilet、VisitBedroom这三个方法就能够达到我们的目的了,这是因为我考虑到访客他自己的参观顺序,这个参观顺序也是访客自己决定的,作为房屋是不能够去限定访客的参观顺序的,所以添加了Visit方法。

如果这篇文章对你有帮助,请给作者点个赞吧!

Visitor模式(访客模式)相关推荐

  1. android访客模式,访客模式:我的隐私我做主_小米 红米Note(增强版/移动3G/2GB RAM)_手机Android频道-中关村在线...

    访客模式 相信每个人的手机中总有一些比较私密的短信.照片.程序等,当然对于这些东西我们并不想被别人知道和看见.而在日常生活中,总避免不了别人偶尔使用或者查看自己的手机,那么这些私密的东西就会让我们变得 ...

  2. Go设计模式--访客模式

    大家好,这里是每周都在陪你一起进步的网管-!今天继续学习设计模式-访客模式 访客模式也叫访问者模式(Visitor Pattern)是一种将数据结构对象与数据操作分离的设计模式,可以在不改变数据结构对 ...

  3. unity3d 收费模式_unity3d中的访客模式

    unity3d 收费模式 抽象 (Abstract) Game development as a discipline is challenging on its own compared to tr ...

  4. Multiple users(Guest mode) 多用户或访客模式调试

    Multiple users(Guest mode) debug 多用户模式(访客模式) 详细见: https://blog.csdn.net/qq_14978113/article/details/ ...

  5. java 访客模式,设计模式 - 访客模式( Visitor Pattern)

    设计模式 - 访客模式( Visitor Pattern) 在Visitor模式中,我们使用一个访问者类来更改元素类的执行算法. 通过这种方式,元素的执行算法可以随着访问者的变化而变化. 此模式属于行 ...

  6. instanceof运算符_Java 8中的instanceof运算符和访客模式替换

    instanceof运算符 我有一个梦想,不再需要操作员和垂头丧气的instanceof ,却没有访客模式的笨拙和冗长. 所以我想出了以下DSL语法: Object msg = //...whenTy ...

  7. Java 8中的instanceof运算符和访客模式替换

    我有一个梦想,不再需要操作员和垂头丧气的instanceof ,却没有访客模式的笨拙和冗长. 所以我想出了以下DSL语法: Object msg = //...whenTypeOf(msg).is(D ...

  8. oracle无效的关系运算符_每日一课 | Java 8中的instanceof运算符和访客模式替换

    我有一个梦想,不再需要操作员和垂头丧气的instanceof ,却没有访客模式的笨拙和冗长.所以我想出了以下DSL语法: Object msg = //... whenTypeOf(msg).     ...

  9. 访客模式 无痕模式 区别_模式:访客模式

    访客模式 无痕模式 区别 问候, 这周我们放开所有代数的内容,然后集中精力 面向对象编程的全部内容. Java声称支持OO,因此 为什么不使用它? 在本周的文章中,我们将讨论一下何时 以及为什么要应用 ...

最新文章

  1. python中name没有定义_Python;NameError:未定义名称“handsum”
  2. .NET跨平台实践:.NetCore、.Net5/6 Linux守护进程设计
  3. 从Java类到对象的创建过程都做了些啥?内存中的对象是啥样的?
  4. C语言学习及应用笔记之六:C语言extern关键字及其使用
  5. IDEA的debug查看某一变量或字段的具体值
  6. ArcEngine和GDAL读写栅格数据机制对比(一)
  7. 用c#算成绩的总和_用c#输入几门课程成绩求总成绩和平均成绩,定义方法实现如果输入的成绩不是整数,则重新输入(方法)...
  8. ECSHOP 如何删除商品列表页 购买弹出 商品属性框后面的价格
  9. mysql如何容器化_MySQL容器化详细教程
  10. Eclipse中执行Tomcat源代码
  11. java基础总结06-常用api类-Arrays
  12. 【JS】经典的对联广告代码,JS代码实现
  13. Android跨进程通信--AIDL原理解析
  14. 社科院与杜兰大学金融管理硕士项目——在职读研是吸引力效应吗?
  15. mac日历与iphone日历不无法同步问题
  16. 市值仅剩5亿美元,猎豹移动为何赢了财报却输了市值?
  17. java雷霆战机源代码_java spring雷霆战机(小游戏源码)
  18. ANSYS ICEM CFD二维结构网络生成实例——流动传热
  19. Eclipse ADT插件和Android SDK使用离线包升级笔记
  20. linux 复制 u盘 只读,Linux_ubuntu系统下向U盘拷贝数据提示目标是只读的,在ubuntu11.04下使用U盘的时候, - phpStudy...

热门文章

  1. 韩顺平 php 聪明的小猫代码,聪明的小猫作文100字
  2. 爬虫进阶:反反爬虫技术--5 网页隐藏信息
  3. 在html如何将链接隐藏,网页查看隐藏链接的方法和检测工具(附:网站链接隐藏的方法)...
  4. 如何使用CommandArgument属性根据id删除记录
  5. 提示:吃鱼进补也要对症
  6. 浪涌(Surge)抗扰度标准解读
  7. 设置table中的td宽度不同
  8. 一个py做的目录小说下载器
  9. PHP-SOCKETS读书笔记1-3
  10. linux 内核版本 4.4,Linux Kernel 4.4 正式发布下载