访问者模式通过分离数据结构与操作,在Go中实现灵活扩展。定义Element接口及Accept方法,让TextElement和ImageElement接受Visitor访问;Visitor接口包含VisitText和VisitImage方法,不同操作如HTML导出、字数统计、敏感词检查分别实现该接口;新增操作无需修改元素类,只需添加新访问者;使用时遍历元素调用Accept传入具体访问者,执行对应逻辑;适用于文档处理、AST解析等场景,但需为每种元素实现所有访问者方法,存在样板代码。

在Go语言中实现访问者模式,主要是为了解决在不修改原有数据结构的前提下,动态添加新的操作逻辑。这种设计模式特别适合数据结构相对稳定,但需要频繁扩展操作的场景。
将数据结构与作用于结构上的操作分离,使得操作可以独立变化。通过定义一个访问者接口,让不同的操作实现该接口,从而实现对同一组对象的不同处理逻辑。
以一个简单的文档处理系统为例,假设我们有文本元素和图片元素,未来可能需要添加导出为HTML、统计字数、校验内容等多种操作。
type Element interface {
Accept(visitor Visitor)
}
type TextElement struct {
Content string
}
func (t *TextElement) Accept(visitor Visitor) {
visitor.VisitText(t)
}
type ImageElement struct {
URL string
}
func (i *ImageElement) Accept(visitor Visitor) {
visitor.VisitImage(i)
}
type Visitor interface {
VisitText(*TextElement)
VisitImage(*ImageElement)
}
// 导出为HTML的操作
type HTMLExportVisitor struct{}
func (h *HTMLExportVisitor) VisitText(t *TextElement) {
print("<p>" + t.Content + "</p>")
}
func (h *HTMLExportVisitor) VisitImage(i *ImageElement) {
print("<img src='" + i.URL + "' />")
}
// 统计字数的操作
type WordCountVisitor struct {
Count int
}
func (w *WordCountVisitor) VisitText(t *TextElement) {
words := strings.Split(strings.TrimSpace(t.Content), " ")
if len(words) > 0 && words[0] != "" {
w.Count += len(words)
}
}
func (w *WordCountVisitor) VisitImage(i *ImageElement) {
w.Count += 5 // 假设每张图相当于5个词
}当需要新增功能时,比如添加“敏感词检查”,只需定义新的访问者,无需改动 TextElement 或 ImageElement:
立即学习“go语言免费学习笔记(深入)”;
type SensitiveCheckVisitor struct {
Found bool
}
func (s *SensitiveCheckVisitor) VisitText(t *TextElement) {
if strings.Contains(t.Content, "badword") {
s.Found = true
}
}
func (s *SensitiveCheckVisitor) VisitImage(i *ImageElement) {
if strings.Contains(i.URL, "unsafe") {
s.Found = true
}
}调用示例:
elements := []Element{
&TextElement{Content: "Hello world"},
&ImageElement{URL: "logo.png"},
}
htmlVisitor := &HTMLExportVisitor{}
for _, e := range elements {
e.Accept(htmlVisitor)
}
wordCounter := &WordCountVisitor{}
for _, e := range elements {
e.Accept(wordCounter)
}
fmt.Println("Word count:", wordCounter.Count)基本上就这些。通过访问者模式,Go语言也能很好地支持“在不修改结构的情况下动态添加操作”的需求。关键是让每个元素主动接受访问者,并调用对应的方法,从而把执行逻辑交给外部。这种方式在处理AST、文档模型、UI组件树等场景中非常实用。不复杂但容易忽略的是:必须为每种元素类型在每个访问者中实现对应方法,类型多了会有些样板代码。
以上就是Golang访问者模式写法 动态添加操作功能的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号