0

0

如何用Golang实现访问者模式 基于接口的双重分发技巧

P粉602998670

P粉602998670

发布时间:2025-07-04 09:44:05

|

365人浏览过

|

来源于php中文网

原创

访问者模式通过双重分发解耦数据结构与操作。其核心在于:1. 定义 element 接口,包含 accept 方法;2. 定义 visitor 接口,包含多个 visit 方法;3. 具体 element 实现 accept 并调用对应 visit 方法。在 golang 中,虽无继承机制,但通过接口实现双重分发,即运行时根据 element 和 visitor 的实际类型决定调用的具体方法。示例中 book 和 dvd 实现 accept,并由 pricevisitor 统一处理打印价格。该模式要求清晰设计接口,新增 element 需同步更新所有 visitor 实现,适合结构稳定、需统一处理的场景,且可通过抽象工厂或依赖注入提升扩展性。

如何用Golang实现访问者模式 基于接口的双重分发技巧

访问者模式的核心在于解耦数据结构和作用于其上的操作。在 Golang 中,虽然没有继承机制,但通过接口(interface)可以巧妙地实现“双重分发”,从而模拟访问者模式的行为。

如何用Golang实现访问者模式 基于接口的双重分发技巧

这篇文章就来聊聊如何用 Golang 实现访问者模式,重点是基于接口的双重分发技巧。

如何用Golang实现访问者模式 基于接口的双重分发技巧

什么是访问者模式?

访问者模式允许你定义一组操作,这些操作可以作用于某个对象结构中的不同元素,而无需修改这些元素本身的类。这种模式特别适合需要对复杂对象结构进行统一处理的场景。

立即学习go语言免费学习笔记(深入)”;

核心概念有两个:

如何用Golang实现访问者模式 基于接口的双重分发技巧
  • Element:被访问的对象,它提供一个接受访问者的方法(比如 Accept(v Visitor))。
  • Visitor:访问者接口,定义一系列 VisitXxx 方法,对应不同的 Element 类型。

关键点在于:访问者调用元素的 Accept 方法,而元素又反过来调用访问者的 Visit 方法,这就是所谓的“双重分发”。


如何用 Golang 接口实现双重分发

Golang 没有类和继承,但可以通过接口和函数组合实现类似效果。下面是具体步骤:

  1. 定义 Visitor 接口,里面包含多个 Visit 方法,分别对应不同类型的 Element。
  2. 定义 Element 接口,必须有一个 Accept 方法,参数为 Visitor。
  3. 各个具体的 Element 结构体实现 Accept 方法,并在里面调用对应的 Visit 方法。

举个简单例子,假设我们有两个元素类型:Book 和 DVD,我们要实现打印价格的操作。

魔法映像企业网站管理系统
魔法映像企业网站管理系统

技术上面应用了三层结构,AJAX框架,URL重写等基础的开发。并用了动软的代码生成器及数据访问类,加进了一些自己用到的小功能,算是整理了一些自己的操作类。系统设计上面说不出用什么模式,大体设计是后台分两级分类,设置好一级之后,再设置二级并选择栏目类型,如内容,列表,上传文件,新窗口等。这样就可以生成无限多个二级分类,也就是网站栏目。对于扩展性来说,如果有新的需求可以直接加一个栏目类型并新加功能操作

下载
type Visitor interface {
    VisitBook(book *Book)
    VisitDVD(dvd *DVD)
}

type Element interface {
    Accept(visitor Visitor)
}

具体元素:

type Book struct {
    Price float64
}

func (b *Book) Accept(visitor Visitor) {
    visitor.VisitBook(b)
}

type DVD struct {
    Price float64
}

func (d *DVD) Accept(visitor Visitor) {
    visitor.VisitDVD(d)
}

然后定义一个打印价格的访问者:

type PriceVisitor struct{}

func (v *PriceVisitor) VisitBook(book *Book) {
    fmt.Println("Book price:", book.Price)
}

func (v *PriceVisitor) VisitDVD(dvd *DVD) {
    fmt.Println("DVD price:", dvd.Price)
}

这样就可以统一处理了:

elements := []Element{
    &Book{Price: 59.9},
    &DVD{Price: 39.9},
}

visitor := &PriceVisitor{}

for _, e := range elements {
    e.Accept(visitor)
}

为什么说这是“双重分发”?

双重分派的意思是:方法调用不是只看调用者的静态类型,而是根据运行时两个对象的实际类型决定调用哪个方法。

在上面的例子中:

  • 第一次分发发生在调用 e.Accept(visitor) 的时候,Go 根据 e 的实际类型调用对应结构体的 Accept 方法。
  • 第二次分发发生在 visitor.VisitXXX(e) 这一步,根据 visitor 的类型和 e 的类型,最终调用了正确的 Visit 方法。

虽然 Go 是静态语言,也没有重载,但通过这种方式实现了类似动态双分发的效果。


使用访问者模式的一些注意事项

  • 接口设计要清晰,每个 Visit 方法应该对应一种 Element 类型。
  • 如果新增 Element 类型,就必须同步更新所有 Visitor 实现,否则会遗漏逻辑。
  • 不适合频繁变动的结构,维护成本较高。
  • 可以配合抽象工厂或依赖注入使用,提升扩展性。

如果你发现 Visitor 接口变得越来越大,可能说明职责划分有问题,可以考虑拆分访问者功能。


基本上就这些。访问者模式在 Golang 中虽然不如 Java 那样自然,但通过接口和双重分发机制,依然可以优雅地实现。关键是理解 Accept 和 Visit 的调用关系,以及 Visitor 接口的设计方式。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

825

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

724

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

728

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

395

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

445

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

428

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16881

2023.08.03

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
golang socket 编程
golang socket 编程

共2课时 | 0.1万人学习

nginx浅谈
nginx浅谈

共15课时 | 0.8万人学习

golang和swoole核心底层分析
golang和swoole核心底层分析

共3课时 | 0.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号