Go通过接口和多态实现访问者模式,将数据结构与操作分离,支持在不修改元素类的情况下动态添加新操作;核心角色包括Element、ConcreteElement、Visitor和ConcreteVisitor,通过Accept方法接收访问者,并在具体类型中调用对应Visit方法完成分发;示例中构建文件系统结构,实现打印和统计大小功能,新增操作只需扩展Visitor接口的实现,符合开闭原则。
在Go语言中实现访问者模式,关键在于解耦对象结构与作用于其上的操作。虽然Go没有继承机制和方法重载,但通过接口和多态依然可以优雅地实现该模式。下面直接进入核心思路和具体实现。
访问者模式允许你在不修改对象类的前提下,为一组对象动态添加新操作。它将“数据结构”与“作用于数据的操作”分离,使得操作可以独立变化。
典型应用场景包括:解析AST(抽象语法树)、序列化不同类型的节点、对多种元素统一执行日志或校验逻辑等。
主要角色有:
由于Go不支持函数重载,不能像Java那样让访问者有多个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方法,把自身传递给访问者,由访问者根据类型分发处理逻辑。
接下来定义访问者接口,明确要支持哪些类型的访问:
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 *SizeVisito
r) 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方法,避免循环引用或遗漏类型。
# java
# go
# golang
# go语言
# ai
相关文章:
如何在Windows 2008云服务器安全搭建网站?
建站之星免费模板:自助建站系统与智能响应式一键生成
如何快速打造个性化非模板自助建站?
如何基于PHP生成高效IDC网络公司建站源码?
建站OpenVZ教程与优化策略:配置指南与性能提升
台州网站建设制作公司,浙江手机无犯罪记录证明怎么开?
寿县云建站:智能SEO优化与多行业模板快速上线指南
制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?
济南企业网站制作公司,济南社保单位网上缴费步骤?
如何规划企业建站流程的关键步骤?
已有域名和空间如何快速搭建网站?
建站之星2.7模板:企业网站建设与h5定制设计专题
香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化
c++23 std::expected怎么用 c++优雅处理函数错误返回【详解】
宝塔新建站点报错如何解决?
建站之星2.7模板快速切换与批量管理功能操作指南
网站好制作吗知乎,网站开发好学吗?有什么技巧?
网站制作的软件有哪些,制作微信公众号除了秀米还有哪些比较好用的平台?
详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)
Dapper的Execute方法的返回值是什么意思 Dapper Execute返回值详解
网站建设设计制作营销公司南阳,如何策划设计和建设网站?
百度网页制作网站有哪些,谁能告诉我百度网站是怎么联系?
广州建站公司哪家好?十大优质服务商推荐
网站制作公司排行榜,抖音怎样做个人官方网站
视频网站app制作软件,有什么好的视频聊天网站或者软件?
免费ppt制作网站,有没有值得推荐的免费PPT网站?
自助网站制作软件,个人如何自助建网站?
中山网站制作网页,中山新生登记系统登记流程?
建站为何优先选择香港服务器?
深圳网站制作案例,网页的相关名词有哪些?
音乐网站服务器如何优化API响应速度?
mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?
制作网站的过程怎么写,用凡科建站如何制作自己的网站?
网站制作难吗安全吗,做一个网站需要多久时间?
c++如何打印函数堆栈信息_c++ backtrace函数与符号名解析【方法】
如何在IIS中新建站点并解决端口绑定冲突?
如何快速搭建安全的FTP站点?
香港服务器网站推广:SEO优化与外贸独立站搭建策略
如何快速生成高效建站系统源代码?
建站org新手必看:2024最新搭建流程与模板选择技巧
建站之星代理如何获取技术支持?
建站之星如何优化SEO以实现高效排名?
学校免费自助建站系统:智能生成+拖拽设计+多端适配
建站之星在线客服如何快速接入解答?
制作网站的公司有哪些,做一个公司网站要多少钱?
如何高效搭建专业期货交易平台网站?
,网页ppt怎么弄成自己的ppt?
建站之星安装步骤有哪些常见问题?
建站之星如何开启自定义404页面避免用户流失?
免费网站制作appp,免费制作app哪个平台好?
*请认真填写需求信息,我们会在24小时内与您取得联系。