Golang Visitor结构遍历访问者模式示例

Visitor 模式在 Go 中用于分离算法与对象结构,通过定义 Element 接口和 Visitor 接口实现对文件系统等复合结构的遍历操作。示例中 File 和 Directory 实现 Accept 方法,分别接受 PrintVisitor 打印名称和 SizeVisitor 统计大小,输出显示遍历结果与总大小 350 字节,适用于操作多类型对象且需扩展新行为的场景。

golang visitor结构遍历访问者模式示例

在 Go 语言中,Visitor 模式常用于对一组结构不同的对象进行统一操作,而又不改变它们的结构。它将算法与对象结构分离,通过“访问者”来定义作用于元素的新操作。

Visitor 模式核心结构

Visitor 模式通常包含以下部分:

Element 接口:定义 Accept 方法,接受一个访问者。 ConcreteElement:具体元素类型,实现 Accept 方法。 Visitor 接口:定义 Visit 方法,对应不同元素类型。 ConcreteVisitor:具体访问者,实现对每种元素的操作。

示例:文件系统遍历

假设我们有一个简单的文件系统结构,包含文件和目录,想对它们分别执行“打印名称”和“统计大小”的操作。使用 Visitor 模式可以解耦数据结构与行为。

package mainimport "fmt"// Element 接口type FileSystemElement interface {    Accept(visitor Visitor)}// 文件结构type File struct {    Name string    Size int}func (f *File) Accept(visitor Visitor) {    visitor.VisitFile(f)}// 目录结构type Directory struct {    Name     string    Elements []FileSystemElement}func (d *Directory) Accept(visitor Visitor) {    visitor.VisitDirectory(d)    for _, e := range d.Elements {        e.Accept(visitor) // 递归访问子元素    }}// Visitor 接口type Visitor interface {    VisitFile(*File)    VisitDirectory(*Directory)}// 打印访问者type PrintVisitor struct{}func (v *PrintVisitor) VisitFile(f *File) {    fmt.Printf("文件: %sn", f.Name)}func (v *PrintVisitor) VisitDirectory(d *Directory) {    fmt.Printf("目录: %sn", d.Name)}// 统计大小访问者type SizeVisitor struct {    TotalSize int}func (v *SizeVisitor) VisitFile(f *File) {    v.TotalSize += f.Size}func (v *SizeVisitor) VisitDirectory(d *Directory) {    // 目录本身不占空间,可忽略或加固定开销}func main() {    root := &Directory{        Name: "根目录",        Elements: []FileSystemElement{            &File{Name: "a.txt", Size: 100},            &File{Name: "b.go", Size: 200},            &Directory{                Name: "子目录",                Elements: []FileSystemElement{                    &File{Name: "c.txt", Size: 50},                },            },        },    }    // 使用打印访问者    printVisitor := &PrintVisitor{}    fmt.Println("=== 打印文件结构 ===")    root.Accept(printVisitor)    // 使用统计大小访问者    sizeVisitor := &SizeVisitor{}    fmt.Println("n=== 统计总大小 ===")    root.Accept(sizeVisitor)    fmt.Printf("总大小: %d 字节n", sizeVisitor.TotalSize)}

输出结果

运行上述代码会得到:

Shakker Shakker

多功能AI图像生成和编辑平台

Shakker 103 查看详情 Shakker

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

=== 打印文件结构 ===目录: 根目录文件: a.txt文件: b.go目录: 子目录文件: c.txt=== 统计总大小 ===总大小: 350 字节

优点与适用场景

Visitor 模式适合以下情况:

需要对多种类型的对象执行不同操作,且操作频繁变化。 希望避免在对象结构中添加大量逻辑代码。 需要集中管理某类算法,比如序列化、渲染、分析等。

Go 语言没有方法重载,因此通过接口和多态实现访问者分发是常见做法。虽然写法略显冗长,但结构清晰,扩展性强。

基本上就这些。

以上就是Golang Visitor结构遍历访问者模式示例的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1133565.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月2日 17:27:21
下一篇 2025年12月2日 17:27:42

相关推荐

发表回复

登录后才能评论
关注微信