新闻中心

如何用Golang实现访问者模式操作不同对象_Golang 访问者模式操作对象实践

2025-11-24
浏览次数:
返回列表
Go通过接口和多态实现访问者模式,将数据结构与操作分离,支持在不修改元素类的情况下动态添加新操作;核心角色包括Element、ConcreteElement、Visitor和ConcreteVisitor,通过Accept方法接收访问者,并在具体类型中调用对应Visit方法完成分发;示例中构建文件系统结构,实现打印和统计大小功能,新增操作只需扩展Visitor接口的实现,符合开闭原则。

如何用golang实现访问者模式操作不同对象_golang 访问者模式操作对象实践

在Go语言中实现访问者模式,关键在于解耦对象结构与作用于其上的操作。虽然Go没有继承机制和方法重载,但通过接口和多态依然可以优雅地实现该模式。下面直接进入核心思路和具体实现。

理解访问者模式的核心思想

访问者模式允许你在不修改对象类的前提下,为一组对象动态添加新操作。它将“数据结构”与“作用于数据的操作”分离,使得操作可以独立变化。

典型应用场景包括:解析AST(抽象语法树)、序列化不同类型的节点、对多种元素统一执行日志或校验逻辑等。

主要角色有:

  • Element:定义接受访问者的接口
  • ConcreteElement:具体被访问的对象
  • Visitor:定义访问每种对象的方法
  • ConcreteVisitor:具体操作的实现者

用接口模拟访问者行为

由于Go不支持函数重载,不能像J*a那样让访问者有多个visit方法。我们通过统一的Accept方法传入访问者,并在具体类型中调用对应处理函数。

示例:定义一个文件系统结构,包含文件和目录:

type Element interface {
    Accept(Visitor)
}

type File struct {
    Name string
    Size int
}

func (f *File) Accept(v Visitor) {
    v.VisitFile(f)
}

type Directory struct {
    Name     string
    Elements []Element
}

func (d *Directory) Accept(v Visitor) {
    v.VisitDirectory(d)
}

这里每个具体元素都实现了Accept方法,把自身传递给访问者,由访问者根据类型分发处理逻辑。

美图云修 美图云修

商业级AI影像处理工具

美图云修 50 查看详情 美图云修

定义访问者接口并实现具体操作

接下来定义访问者接口,明确要支持哪些类型的访问:

type Visitor interface {
    VisitFile(*File)
    VisitDirectory(*Directory)
}

// 打印信息的访问者
type PrintVisitor struct{}

func (pv *PrintVisitor) VisitFile(f *File) {
    println("File:", f.Name, "(size:", f.Size, "bytes)")
}

func (pv *PrintVisitor) VisitDirectory(d *Directory) {
    println("Directory:", d.Name)
    for _, e := range d.Elements {
        e.Accept(pv)
    }
}

// 统计总大小的访问er
type SizeVisitor struct {
    Total int
}

func (sv *SizeVisitor) VisitFile(f *File) {
    sv.Total += f.Size
}

func (sv *SizeVisitor) VisitDirectory(d *Directory) {
    for _, e := range d.Elements {
        e.Accept(sv)
    }
}

这样就实现了两个独立功能:打印结构和计算总大小,且都不需要改动File或Directory的代码。

使用方式简单直观

构建对象结构并应用访问者:

func main() {
    root := &Directory{
        Name: "root",
        Elements: []Element{
            &File{Name: "a.txt", Size: 100},
            &File{Name: "b.go", Size: 200},
            &Directory{
                Name: "sub",
                Elements: []Element{
                    &File{Name: "c.txt", Size: 50},
                },
            },
        },
    }

    // 打印结构
    root.Accept(&PrintVisitor{})

    // 计算总大小
    sv := &SizeVisitor{}
    root.Accept(sv)
    println("Total size:", sv.Total) // 输出 350
}

新增操作只需添加新的Visitor实现,无需修改现有元素类,符合开闭原则。

基本上就这些。Go通过接口+方法绑定的方式,完全可以胜任访问者模式的实现,关键是设计好Element的Accept流程和Visitor的类型分发逻辑。不复杂但容易忽略的是:确保所有ConcreteElement正确调用对应的Visit方法,避免循环引用或遗漏类型。

以上就是如何用Golang实现访问者模式操作不同对象_Golang 访问者模式操作对象实践的详细内容,更多请关注其它相关文章!


# 并在  # 三明网站建设机构推荐  # seo知识技术学习  # 河南网站推广免费  # 吴川公司网站建设方案  # 学生会网站建设  # 达州营销推广一般多少钱  # 安阳质量好网站推广技巧  # 顺昌县网站建设建议  # 农药策划营销推广方案  # 保定seo搜索优化价格  # 命令行  # 文件系统  # java  # 只需  # 多态  # 迭代  # 美图  # 如何用  # 数据结构  # 遍历  # ai  # go语言  # golang  # go 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 微信商城在哪里打开【步骤】  J*aScript中在Map循环中检测并处理空数组元素  神经网络二分类模型训练异常:高损失与完美验证准确率的排查与修正  在J*a中如何使用BigDecimal进行高精度计算_BigDecimal类应用指南  Golang指针如何与map组合使用_Golang map指针组合实践  HTML转PPT成品工具有哪些?HTML网页转PPT成品工具大全  CSS自定义字体样式被系统字体替换怎么办_font-face方式指定font-display控制渲染策略  QQ邮箱网页版入口页面 QQ邮箱在线登录入口官网  Pandas DataFrame:高效添加条件计算列  Python多线程中正确使用sigwait处理SIGALRM信号  漫蛙2在线漫画入口 漫蛙正版漫画网页版直达  58动漫网在线官方网 58动漫网正版动漫入口网址  Spring Boot嵌入式服务器与J*a EE:功能支持深度解析  Pandas DataFrame 多条件优先级排序与排名  Centos/Linux 系统下安装 composer 的完整步骤  Win11怎么用U盘重装系统 Win11制作启动盘并重装系统完整教程【详解】  J*aScript Promise链中如何正确终止后续.then执行并处理错误  谷歌浏览器怎么给标签页静音_Chrome标签静音快捷操作  c++如何使用std::memory_order控制原子操作顺序_c++ C++11内存模型详解  夸克浏览器图书入口 夸克手机浏览器阅读入口  wps文字怎么插入目录并自动更新_wps文字如何插入目录并自动更新方法  如何使用纯J*aScript判断Input元素是否在特定类容器内  excel如何生成目录 excel一键生成工作表目录超链接  如何使用 Excel 发布器与 Power BI 分享 Excel 洞察  Python中高效且防溢出的双曲正弦计算:基于对数空间的优化策略  搜狗浏览器如何使用密码生成器创建强密码 搜狗浏览器内置密码安全工具  《噬血代码2》新预告片发布 展示游戏剧情  从J*aScript对象中精确提取指定属性的教程  c++如何实现单例设计模式_c++线程安全的单例模式写法  Windows10怎么开启夜间模式 Windows10系统设置调整色温与亮度缓解夜间用眼疲劳【教程】  Archive of Our Own官网直达 AO3最新可用地址一览  Typer应用中灵活处理命令行参数的令牌化与解析  如何使用CaptainHook和Composer管理Git钩子_在提交前自动运行代码检查的Composer配置  顺丰快件物流信息 官方网站查询入口  Word2013如何插入视频和音频媒体_Word2013媒体插入的多媒体支持  QQ邮箱网页版入口登录 QQ邮箱在线邮箱官方通道  Lar*el的路由模型绑定怎么用_Lar*el Route Model Binding简化控制器逻辑  俄罗斯浏览器官网直达链接 俄罗斯浏览器最新在线入口导航  小猿搜题在线学习页面在哪_小猿搜题在线学习中心入口  如何优雅地扩展SprykerGlue后端API授权逻辑,使用spryker/glue-backend-api-application-authorization-connector-extension  steam官方网页快速访问 steam账号注册全流程  汽水音乐在线版入口_汽水音乐网页播放手册  漫蛙官网正版漫画入口 漫蛙2官方网页登录地址  TikTok国际版网页端快速入口 TikTok全球版短视频浏览教程  解决Python单元测试中Mock异常方法调用计数为零的问题  yandex入口引擎手机版 yandex安卓版下载入口  Golang如何优化内存分配与垃圾回收_Golang内存管理与GC优化实践  J*aScript井字棋(Tic-Tac-Toe)核心交互逻辑实现教程  知音漫客正版漫画平台_知音漫客官网账号登录  windows10怎么查看本机ip_windows10命令提示符ipconfig使用 

搜索