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

行为型模式,我之所以把他放到第一个,是因为它号称是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. python tcp select 多路复用

    1 #!/usr/bin/python 2 # -*- coding: UTF-8 -*- 3 # 文件名:tcpserver.py 4 5 import socket 6 import time 7 ...

  2. node 学习笔记 模块和包的管理与使用

    1.前言 对于各种编程语言,代码组织是很重要的.而模块是node中的代码组织机制,node中的很多功能都以模块划分,而模块中又封装了许多方法,而且不会改变全局作用域,极大的方便了各开发者的需求. 2. ...

  3. Pycharm系列---QT配置

    PYSIDE2 添加外部工具 file---settings External Tools,点击左上角的 加号+ designer 位置: envs\QT6\Lib\site-packages\PyS ...

  4. 解决头部使用 position:fixed; 固定定位后遮住下方内容的问题

    1.在头部下面给一个空的 div 给这个div设置高度,把页面撑开,这种方法是让头部刚好遮住的是这个空div,把内容放出来. 但是这种方法需要一点点调试高度,所以不推荐. 2.把整个要使用 posit ...

  5. 如何实现一个优秀的 HashTable 散列表?

    本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问. 前言 大家好,我是小彭. 在前几篇文章里,我们聊到了 Java 中的几种线性表结构,包括 ArrayList ...

  6. WINDOWS下对NIGNX日志文件进行限制

    首先接到这个任务,发现nginx的日志限制更多的都是在Linux下做的,找了半天,也没找到能直接通过nginx.conf更改体现到日志限制上的. 最后决定直接通过bat脚本,来对nginx的日志进行分 ...

  7. Azure DevOps Server 用户组加入 Azure AD Domain Service 管理用户

    一,引言 今天我们继续讲解 Azure DevOps Server 的内容,对于管理用户组除了在 Azure DevOps Server 服务器上添加管理员方式外,还有没有其他方式,Azure Dev ...

  8. 【PostgreSQL/PGSQL】创建分区表与临时表

    一.分区表 1.链接 https://blog.csdn.net/zhangyupeng0528/article/details/119423234 2.分类 列(值)分区表:partition by ...

  9. 《HTTP权威指南》– 8.网关、Web机器人

    集成点:网关.隧道及中继 网关 网关(gateway): 资源和应用程序之间的粘合剂.应用程序可以(通过HTTP或其它已定义的接口)请求网关来处理某条请求,网关可以提供一条响应.网关可以向数据库发送查 ...

  10. Django框架F查询与Q查询(全面了解)

    一:F与Q查询 1.F查询的作用 能够帮助你直接获取到列表中某个字段对应的数据 注意: 在操作字符串类型的数据的时候, F不能够直接做到字符串的拼接 2.查询卖出书大于库存数的书籍 # 导入F查询 f ...