概述
自用学习笔记
设计模式
【狂神说Java】通俗易懂的23种设计模式教学(停更)_哔哩哔哩_bilibili
【2021版】马士兵重讲23种设计模式,居然能这么通俗易懂_哔哩哔哩_bilibili
23种设计模式
- 设计模式概述
概念:设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。
- 主要针对面向对象软件设计
- 95年,GoF四人帮合伙出了一本书,收录23设计模式,又称GoF设计模式
学习一个设计模式要了解的:1)模式名称;2)要解决的问题;3)解决问题的方案;4)效果(该模式的优缺点)
23种模式:
创建型模式:描述如何创建一个对象,st对象的创建和使用分离
结构型模式:
行为型模式:描述类之间如何相互协作 完成某种行为
- 访问者模式
【2021版】马士兵重讲23种设计模式,居然能这么通俗易懂_哔哩哔哩_bilibili
在结构不变的情况下,动态改变对于内部元素的动作
例子:编译器中,做语法分析时对AST的分析,就要用到visitor模式。(例如babel的AST 就是用的visitor模式的设计思路)
例子:
Computer类由cpu、内存、主板组成,他们都是抽象类ComputerPart
现在模拟攒机:
现在需求:个人用户(学生或上班族打不同折扣)来攒机可以打少量折扣、企业用户来攒机可以打很多折扣
解决办法:
法一:
在CPU里面写一个accept方法 接受一个visitor(用户),然后里面用各种if判断来的用户是啥 然后给xxx折扣
但这种写法不好:
- 把各种if语句都要写到CPU memory board里
- 如果要新增一种用户折扣 又要在每个computerpart里面改,改的东西太多了
法二:即上面代码实现的功能,比如cpu的accept方法就调用visitor.visitCPU()方法,要求每个来访者都实现visitCPU visitmemory等方法。
重点:
1)Computer(某个大结构,如树)的子结构接待来访者
2)具体的接待策略由来访者自己定义、实现
看代码:
这样 就实现了不同来访者访问相同子结构,实现的效果不一样
看下面结构图:
重点:
- 子结构需要有接受visitor的accept方法
- Accept方法中调用visitor的访问自己的方法
- 不同的visitor要各自实现访问不同子结构的方法
【比如上面图的例子 AST有不同类型节点 访问者有不同类型(如typecheck、codegenerate等)】
Visitor模式的好处/特点:
- computer类不用再变了,除非你要加新的子结构【但visitor模式一般适用于访问结构固定的东西,如果这个东西的结构一直在变的,就不适合使用访问者模式】
适用于被处理的数据元素相对稳定,而访问方式多种多样的数据结构。
- 本质是把子结构中的各种if语句抽象到visitor接口里面。本质是把处理方法从数据结构中分离出来,并可以根据需要增加新的处理方法,且不用修改原来的程序代码与数据结构
Visitor模式的应用:(GoF例子)
编译器中对AST做不同操作(如类型检查:比如检查+号操作符左右元素是不是都是数字类型,检查赋值语句两边元素的类型是否一致等;如生成中间代码;如AST beautifier)
即我们需要访问AST(结构固定),且有各种不同的访问的需求(visitor不同)
传统方法:
每个节点都定义visitor的不同动作 很麻烦
Visitor模式方法:
只给节点定义accept 只调用visitor自己的visit方法
然后每种visitor具体要做什么,在自己visitor里面定义,就不写在节点里面了
【所以说babel中的访问节点就是用的visitor模式】
babel-handbook/plugin-handbook.md at master · jamiebuilds/babel-handbook · GitHub
例如在babel plugin的编写中,我们可以自己定义visitor,定义我们访问不同节点时的动作。比如当时我有个插桩的需求,在所有函数定义的开头和结尾加入统计函数执行时间的代码。即我们就可以在定义当我们访问到functiondeclaration节点时,在其子节点插入一个functioncall节点。
而不是在functiondeclaration中改。。。
在现实生活中,有些集合对象存在多种不同的元素,且每种元素也存在多种不同的访问者和处理方式。例如,公园中存在多个景点,也存在多个游客,不同的游客对同一个景点的评价可能不同;医院医生开的处方单中包含多种药元素,査看它的划价员和药房工作人员对它的处理方式也不同,划价员根据处方单上面的药品名和数量进行划价,药房工作人员根据处方单的内容进行抓药。
这样的例子还有很多,例如,电影或电视剧中的人物角色,不同的观众对他们的评价也不同;还有顾客在商场购物时放在“购物车”中的商品,顾客主要关心所选商品的性价比,而收银员关心的是商品的价格和数量。
这些被处理的数据元素相对稳定而访问方式多种多样的数据结构,如果用“访问者模式”来处理比较方便。访问者模式能把处理方法从数据结构中分离出来,并可以根据需要增加新的处理方法,且不用修改原来的程序代码与数据结构,这提高了程序的扩展性和灵活性。
但实际上,Visitor模式的使用场景比较窄,基本就应用编译器这个专业领域了。
代码例子:
https://github.com/TeraniteAK/ProgrammingPractice/tree/main/JavaVisitorDesignPattern
【总结】
1)模式名称:访问者模式
2)要解决的问题:被处理的数据元素相对稳定,而访问方式多种多样的数据结构。即要求用多种访问方式访问一个结构相对固定的数据结构。
3)解决问题的方案:将访问逻辑从数据结构本身抽离出来,把访问逻辑放在visitor中。
4)效果(该模式的优缺点)
- 适用于被处理的数据元素相对稳定,而访问方式多种多样的数据结构。换言之,如果数据结构需要不定期变换,就不适合使用访问者模式
- 把数据结构的处理方式和数据结构本身分离开来,方便增加新的对数据结构的访问/处理方式。
- 实际应用中基本只用在compiler中对AST的访问。
最后
以上就是干净豌豆为你收集整理的设计模式学习笔记:访问者模式(含设计模式概述)的全部内容,希望文章能够帮你解决设计模式学习笔记:访问者模式(含设计模式概述)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复