网站首页 > 博客文章 正文
访问者设计模式
访问者模式是一种行为设计模式,使得可以在向结构添加行为时,而不必修改结构内部的代码。用一个例子来理解访问者模式,假设有表示不同形状Shape的结构体,如下所示:
- 正方形Square
- 圆形Circle
- 三角形Triangle
上面的每个结构实现同一个公共接口shape。假设公司里有很多团队都在使用你编写的库,其中有一个团队希望你在Shape结构中再添加一个行为(求面积getArea())。
此时,解决这个问题有很多种方案可供选择
第一种方案
在shape接口中添加getArea()方法,然后每个shape的实现都要定义这个方法。这看起来很简单直观,但也存在一些问题:
作为库的维护者,您不想过多地修改已经调试完备的代码只为了添加额外的行为,而且可能还有更多来自其它团队添加别的行为的请求(如getNumSides()、getMiddleCoordinates())。在这种情况下,您不想反复地修改库,同时也希望其他团队不必对库源码进行太多修改而又能扩展出他们想要的功能。
第二种方案
第二种选择是,团队编写自己想要的行为逻辑。下面是他们可能会写下的代码,基于主题结构的类型来进行判断
上面的代码也有问题,因为不能充分利用接口的优势,而是执行显式类型检查,这样的代码健壮性不强。其次,在运行时获取对象的类型可能会影响性能,甚至在某些语言中是不可能做到的。
第三种方案
第三种选择是使用观察者模式解决上述问题。
首先,定义了一个访问者接口visitor,如下所示:
visitforSquare(square)、visitForCircle(circle)、visitForTriangle(triangle)函数分别是要向square、circle和triangle添加的新行为的定义。
有一个问题是为什么不只定义一个方法visit(shape),之所以不这样做,是因为GO和其他一些语言支持方法重载,因此每个结构可能都有各自不同的方法。
然后,使用下面的签名向形状接口shape中添加accept方法,每个shape接口的形状实现都需要定义此方法,该方法接受访问者visitor作为参数,并调用访问者内与其类型对应的行为函数。
等一下,刚刚不是提到不想修改现有的形状定义吗?当使用Visitor模式时,需要对主题稍微做些修改,但是这种修改只会进行一次。以后再向主题添加其他行为时(如getNumSides(),getMiddleCoordinates()等等),都可以使用上述相同的accept(v visitor)方法,而不需要再做任何修改。基本上,对形状接口的实现只需修改一次,以后所有其他行为的请求都将使用相同的accept函数处理。让我们看看怎么做:
square结构要实现accept方法如下所示的:
同样地,圆和三角形也会定义各自的accept函数。
现在,团队对求面积行为的请求getArea()可以简单地定义为visitor接口的一个具体实现,并在该实现中分别为每种形状编写求面积的计算逻辑。
以下是求面积行为对visitor接口实现的代码片段:
当要计算正方形的面积,首先创建一个正方形实例,然后创建求面积行为的实例,最后以行为实例作为参数调用正方形accept方法。
类似地,其他团队对其他行为如getMiddleCoordinates()等的需求也可以按照如上所示的方法定义为访问者接口的另一个具体实现。
以下是求中点坐标行为对visitor接口实现的代码片段:
下面是观察者设计模式的UML图:
下面是本例的UML图:
下面是观察者设计模式的组件:
下面是shape.go的代码:
下面是square.go的代码:
下面是circle.go的代码:
下面是rectangle.go的代码:
下面是visitor.go的代码:
下面是areaCalculator.go的代码:
下面是middleCoordinates.go的代码:
下面是main.go的代码:
猜你喜欢
- 2024-10-01 设计模式——备忘录模式(备忘录界面设计)
- 2024-10-01 设计模式 之 行为型模式(行为型设计模式特点)
- 2024-10-01 Spring Boot 实战:运用访问者模式灵活扩展订单处理逻辑
- 2024-10-01 visitor pattern 访问者模式(访问者模式工作原理)
- 2024-10-01 Aha!设计模式(105)-访问者模式(1)
- 2024-10-01 GOF设计模式(命令模式,访问者模式,迭代器模式,观察者模式)
- 2024-10-01 设计模式第2招第9式之解释器模式(解释器原理)
- 2024-10-01 设计模式第2招第1式之观察者模式(观察者设计模式的优点)
- 2024-10-01 「编程设计」访问者(Visitor)模式-补丁式为原体系增加新功能
- 2024-10-01 访问者模式的结构(访问者模式的结构是)
你 发表评论:
欢迎- 07-07Xiaomi Enters SUV Market with YU7 Launch, Targeting Tesla with Bold Pricing and High-Tech Features
- 07-07Black Sesame Maps Expansion Into Robotics With New Edge AI Strategy
- 07-07Wuhan's 'Black Tech' Powers China's Cross-Border Push with Niche Electronics and Scientific Firepower
- 07-07Maven 干货 全篇共:28232 字。预计阅读时间:110 分钟。建议收藏!
- 07-07IT运维必会的30个工具(it运维工具软件)
- 07-07开源项目有你需要的吗?(开源项目什么意思)
- 07-07自动化测试早就跑起来了,为什么测试管理还像在走路?
- 07-07Cursor 最强竞争对手来了,专治复杂大项目,免费一个月
- 最近发表
-
- Xiaomi Enters SUV Market with YU7 Launch, Targeting Tesla with Bold Pricing and High-Tech Features
- Black Sesame Maps Expansion Into Robotics With New Edge AI Strategy
- Wuhan's 'Black Tech' Powers China's Cross-Border Push with Niche Electronics and Scientific Firepower
- Maven 干货 全篇共:28232 字。预计阅读时间:110 分钟。建议收藏!
- IT运维必会的30个工具(it运维工具软件)
- 开源项目有你需要的吗?(开源项目什么意思)
- 自动化测试早就跑起来了,为什么测试管理还像在走路?
- Cursor 最强竞争对手来了,专治复杂大项目,免费一个月
- Cursor 太贵?这套「Cline+OpenRouter+Deepseek+Trae」组合拳更香
- 为什么没人真的用好RAG,坑都在哪里? 谈谈RAG技术架构的演进方向
- 标签列表
-
- ifneq (61)
- 字符串长度在线 (61)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)