行为型模式 - 访问者模式Visitor
学习而来,代码是自己敲的。也有些自己的理解在里边,有问题希望大家指出。
行为型模式,我之所以把他放到第一个,是因为它号称是GoF中最难的一个。
模式的定义与特点
在访问者模式中(Visitor Pattern)中,我们使用了一个访问者类,他改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。根据访问者模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。
模式的优点
- 符合单一职责原则。
- 拥有优秀的扩展性。
- 非常灵活。
模式的缺点
- 具体元素对访问者公布细节,违反了迪米特法则。
- 具体元素变更比较困难。
- 依赖了具体类,没有依赖抽象,这违反了依赖倒置原则。
举例使用场景
说在某个厨师交流会上,有三个人一拍即合要开餐馆。这三个人分别是一个老板、一个中国厨师、一个西方厨师。餐馆开起来后客人络绎不绝,但两位厨师用的没油了,提出要加服务员跑腿。老板不同意啊,多一个人就得多开钱啊,于是让两位厨师自行解决。并且说不管是这次的油,还是之后还有别的需求都让两个厨师自己解决。
分析故事:永远只有三个人,所有事情都需要两个厨师自己解决。
想到的解决办法:
- 更改厨师类,新增获取油或者是其他需求时,进行类的扩展,这样不符合开闭原则
- 抽象厨师类,每次有新的需求时新增一个厨师就行,这样看似符合开闭原则,且解决了问题,但题目内容本身,是不允许新增员工的。
- 被制作的东西告诉厨师:"1、你需要做我。2、我是你怎么做出来的 ",然后厨师做出了这个东西。这样之后厨师需要做什么,原有代码都不需要修改,只需要增加被生产的内容类即可。这样符合开闭原则,也完美的解决了问题。
根据题目与结论得出,应该有俩厨师类,一个被生产类。
俩厨师类来做东西(访问者),通过访问者:“1:告知厨师类需求做出自己,2:告知厨师类怎么制作自己”。
internal class Program {
static void Main(string[] args) {
List<Cooker> cookers = new List<Cooker>() { //获取所有厨师
new ChineseChef(),
new WesternChef(),
};
Visitor meat = new MeatVisitor(); //获取肉类访问者
Visitor oil = new GetOilVisitor(); //获取油类访问者
for (int i = cookers.Count - 1; i >= 0; i--) {
//cookers[i].Cooking(meat); //告诉厨师需要做什么内容(肉)
cookers[i].Cooking(oil); //告诉厨师需要做什么内容(油)
}
Console.ReadLine();
}
}
//===================================================================================================
internal abstract class Cooker { //厨师抽象类
public string Name; //厨师
public abstract void Cooking(Visitor visitors); //抽象出做东西 参数:做的内容(访问者)
}
internal class ChineseChef : Cooker {
public override void Cooking(Visitor visitors) {
Name = "中国厨师";
visitors.Chinesechef(this); //告诉访问者,现在是中国厨师在做
}
}
internal class WesternChef : Cooker {
public override void Cooking(Visitor visitors){
Name = "西方厨师";
visitors.Westernchef(this); //告诉访问者,现在是西方厨师在做
}
}
//===================================================================================================
internal abstract class Visitor { //访问者类抽象
public abstract void Chinesechef(Cooker cookers); //抽象出 中国厨师怎么做自己
public abstract void Westernchef(Cooker cookers); //抽象出 西方厨师怎么做自己
}
internal class MeatVisitor : Visitor { //定义访问者自身为肉
public override void Chinesechef(Cooker cookers) { //告诉中国厨师自己怎么做
Console.WriteLine($"{cookers.Name}认为,肉 要煮的吃");
//Console.WriteLine("中国厨师认为,肉 要煮的吃");
}
public override void Westernchef(Cooker cookers) { //告诉西方厨师自己怎么做
Console.WriteLine($"{cookers.Name}认为,肉 要煎的吃");
//Console.WriteLine("西方厨师认为,肉 要煎的吃");
}
}
internal class GetOilVisitor : Visitor {
public override void Chinesechef(Cooker cookers) {
Console.WriteLine($"{cookers.Name}认为,油 可以通过肉炼出来");
//Console.WriteLine("中国厨师认为,油 可以通过肉炼出来");
}
public override void Westernchef(Cooker cookers) {
Console.WriteLine($"{cookers.Name}认为,油 应该去超市买");
//Console.WriteLine("西方厨师认为,油 应该去超市买");
}
}
希望大家:点赞,留言,关注咯~
唠家常
今日分享结束啦,小伙伴们你们get到了么,你们有没有更好的办法呢,可以评论区留言分享,也可以加我QQ:841298494,大家一起进步。
- 客官,看完get之后记得点赞哟!
- 小伙伴你还想要别的知识?好的呀,分享给你们
今日推荐
行为型模式 - 访问者模式Visitor的更多相关文章
- 【设计模式】行为型09访问者模式(Visitor Pattern)
学习地址:https://blog.csdn.net/u012124438/article/details/70537203(参考了很多博客,只有这个讲明白了核心点) 访问者模式(Visitor P ...
- 【GOF23设计模式】解释器模式 & 访问者模式
来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_解释器模式.访问者模式.数学表达式动态解析库式 1.解释器模式Interpreter 2.访问者模式Visitor
- 访问者(Visitor)模式
http://www.cnblogs.com/zhenyulu/articles/79719.html 一. 访问者(Visitor)模式 访问者模式的目的是封装一些施加于某种数据结构元素之上的操作. ...
- C#设计模式——访问者模式(Visitor Pattern)
一.概述由于需求的改变,某些类常常需要增加新的功能,但由于种种原因这些类层次必须保持稳定,不允许开发人员随意修改.对此,访问者模式可以在不更改类层次结构的前提下透明的为各个类动态添加新的功能.二.访问 ...
- B7:访问者模式 Visitor
表示一个作用于某对象结构中各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 适用场景:1.适用于元素类数据结构相对稳定(类的方法固定,但属性可以变化,如果方法变化很大,就无 ...
- 浅谈设计模式-visitor访问者模式
先看一个和visitor无关的案例.假设你现在有一个书架,这个书架有两种操作,1添加书籍2阅读每一本书籍的简介. //书架public class Bookcase { List<Book> ...
- 折腾Java设计模式之访问者模式
博客原文地址:折腾Java设计模式之访问者模式 访问者模式 Represent an operation to be performed on the elements of an object st ...
- C#设计模式学习笔记:(21)访问者模式
本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/8135083.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第九个模式--访 ...
- [Python设计模式] 第28章 男人和女人——访问者模式
github地址:https://github.com/cheesezh/python_design_patterns 题目 用程序模拟以下不同情况: 男人成功时,背后多半有一个伟大的女人: 女人成功 ...
随机推荐
- python3使用libpcap库进行抓包及数据处理
python版本:python 3.9 libpcap版本:1.11.0b7 python libpcap库是底层绑定c语言libpcap库的开发包,旨在提供python应用可访问的unix c li ...
- 基于LZO的高性能无损数据压缩IP
LZOAccel-C LZO Data Compression Core/无损数据压缩IP Core LZOAccel-C是一个无损数据压缩引擎的FPGA硬件实现,兼容LZO 2.10标准. Core ...
- 「MySQL高级篇」MySQL之MVCC实现原理&&事务隔离级别的实现
大家好,我是melo,一名大三后台练习生,死去的MVCC突然开始拷打我! 引言 MVCC,非常顺口的一个词,翻译起来却不是特别顺口:多版本并发控制. 其中多版本是指什么呢?一条记录的多个版本. 并发控 ...
- Redis系列9:Geo 类型赋能亿级地图位置计算
Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) Redis系列5: ...
- 【深入浅出 Yarn 架构与实现】1-2 搭建 Hadoop 源码阅读环境
本文将介绍如何使用 idea 搭建 Hadoop 源码阅读环境.(默认已安装好 Java.Maven 环境) 一.搭建源码阅读环境 一)idea 导入 hadoop 工程 从 github 上拉取代码 ...
- java学习之socket编程
0x00前言和思维导图 Socks实际上是什么:实际上是提供了精彩通信的端口,在通信之前双方都必须要创造一个端点才能通信,其实感觉socket跟计算机的三次握手有些相似,分为三个步骤: (1)服务器监 ...
- Linux内核替换的一种简单方法
前言 使用现有centos的镜像,在海光机器上出现了无法运行的情况,grub引导后就只剩下光标一直在闪,无任何字符输出.这种情况大概率是因为Linux的内核无法运行在海光的CPU上所导致的. 已得知L ...
- i春秋who are you
打开题目网页,抓包,查源码都一无所获,然后就去看cookie,发现一个role变量,刚开始也不知道这个变量是什么,其值也是没有规律的一串字符串.看了别人源码才知道这是base64加密后的字符串,将其用 ...
- dom xss->半自动化
前几天看了两篇文章,觉得很不错,写一笔,就当笔记记录. 第一篇文章:https://jinone.github.io/bugbounty-dom-xss/ 作者写了自己通过自动化挖dom xss,差不 ...
- GeoServer 2.15.0 开启跨域设置
GeoServe老版本可能开启跨域设置比较麻烦,但2.15.0版本还是比较简单的. 首先找到安装目录下的 webapps\geoserver\WEB-INF\web.xml 文件,打开进行编辑,建议编 ...