学习而来,代码是自己敲的。也有些自己的理解在里边,有问题希望大家指出。

行为型模式,我之所以把他放到第一个,是因为它号称是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的更多相关文章

  1. 【设计模式】行为型09访问者模式(Visitor Pattern)

    学习地址:https://blog.csdn.net/u012124438/article/details/70537203(参考了很多博客,只有这个讲明白了核心点) 访问者模式(Visitor  P ...

  2. 【GOF23设计模式】解释器模式 & 访问者模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_解释器模式.访问者模式.数学表达式动态解析库式 1.解释器模式Interpreter  2.访问者模式Visitor 

  3. 访问者(Visitor)模式

    http://www.cnblogs.com/zhenyulu/articles/79719.html 一. 访问者(Visitor)模式 访问者模式的目的是封装一些施加于某种数据结构元素之上的操作. ...

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

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

  5. B7:访问者模式 Visitor

    表示一个作用于某对象结构中各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 适用场景:1.适用于元素类数据结构相对稳定(类的方法固定,但属性可以变化,如果方法变化很大,就无 ...

  6. 浅谈设计模式-visitor访问者模式

    先看一个和visitor无关的案例.假设你现在有一个书架,这个书架有两种操作,1添加书籍2阅读每一本书籍的简介. //书架public class Bookcase { List<Book> ...

  7. 折腾Java设计模式之访问者模式

    博客原文地址:折腾Java设计模式之访问者模式 访问者模式 Represent an operation to be performed on the elements of an object st ...

  8. C#设计模式学习笔记:(21)访问者模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/8135083.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第九个模式--访 ...

  9. [Python设计模式] 第28章 男人和女人——访问者模式

    github地址:https://github.com/cheesezh/python_design_patterns 题目 用程序模拟以下不同情况: 男人成功时,背后多半有一个伟大的女人: 女人成功 ...

随机推荐

  1. 思维分析逻辑 3 DAY

    目录 指标分析 指标选择原则 指标体系建立 步骤 流量分析 渠道分析(从哪来) 常见渠道及渠道分类 渠道推广过程 渠道的指标 渠道分析方法 转化及价值分析(经过什么?产生什么价值?) 漏斗分析 功能模 ...

  2. qtcreator 报错error: You need to set an executable in the custom run configuration.

    解决 没有配置运行的可执行文件. 在 Executable 中填入正确的可执行文件位置,这里我使用了一个变量,可以根据 release,debug的区别自动找到对应的可执行文件.

  3. <四>虚函数 静态绑定 动态绑定

    代码1 class Base { public: Base(int data=10):ma(data){ cout<<"Base()"<<endl; } v ...

  4. Mybatis-Plus 对 json 的存储使用支持

    Mybatis-Plus 对 json 的存储使用支持 场景分析: 随着数据库对字段类型支持的多元化,json 类型的存储已成为多场景高频使用的字段类型.而 MySql.postgrpSql 等都支持 ...

  5. OpenVINO计算机视觉模型加速

    OpenVINO计算机视觉模型加速 OpenVINO介绍 计算机视觉部署框架,支持多种边缘硬件平台 Intel开发并开源使用的计算机视觉库 支持多个场景视觉任务场景的快速演示 四个主要模块: 1.开发 ...

  6. 说说真实Java项目的开发流程,以及面试前的项目准备说辞

    介绍项目是必不可少的Java面试环节,求职者需要借此证明自己真实Java项目的经验,如果再做的好的话,需要借此展开自己的亮点说辞. 不过之前如果只有学习项目经验,比如是自己跑通一个项目,或者是在培训班 ...

  7. python基础re模块与正则

    正则表达式前戏 正则表达式是用来匹配与查找字符串的,从网上爬取数据自然或多或少会用到正则表达式,python的正则表达式要先引入re模块,正则表达式以r引导 案例:手机号校验 基本要求:手机号必须是1 ...

  8. 自研ORM框架 实现类似EF Core Include 拆分查询 支持自定义条件、排序、选择

    Baozi, I'm Mr.Zhong I like to brush TikTok, I know that anchors like to call it that, haha!Recently, ...

  9. SQLMap入门——判断是否存在注入

    假设目标注入点是http://127.0.0.1/sqli-labs-master/Less-1/?id=1,判断其是否存在注入的命令如下: python sqlmap.py -u http://12 ...

  10. LoadRunner11录制脚本

    1.打开LoadRunner11后界面如下: 2.点击"创建/编辑脚本",会打开一个新窗口,如下: 3.这里新建一个web/html格式的测试.点击"文件"-& ...