访问者模式通过分离操作与数据结构,使Go中复杂对象的多操作处理更灵活。定义Element接口的Accept方法和Visitor接口的Visit方法,让具体元素如Circle、Square在被访问时回调对应Visit实现,从而执行如计算面积、导出JSON等操作。示例中AreaCalculator累加面积,JSONExporter构建JSON字符串,均通过Accept-Visit机制遍历元素完成,新增操作无需修改元素类,符合开闭原则,提升代码可扩展性。

当我们在Go语言中处理那些由不同类型对象组成的复杂数据结构时,比如一个由各种图形(圆形、矩形)构成的文档,并且我们想对这些图形执行多种操作(计算面积、导出JSON、渲染),访问者模式提供了一个优雅的解决方案。它允许我们将操作逻辑与对象结构本身解耦,让我们的代码更具扩展性和维护性,避免了在每个对象里堆砌各种操作,或者写出冗长的类型判断链。简单来说,它让数据结构保持稳定,而操作可以灵活地增删。
要实践Golang的访问者模式,我们核心需要定义两套接口:
Element
Visitor
Element
Accept
Visitor
Circle
Square
Accept
Visitor
Visit
Visitor
Element
Visit
Accept
package main
import (
"fmt"
"math"
"strings" // 用于处理JSON输出的逗号
)
// Element 接口:定义了一个接受访问者的方法
type Element interface {
Accept(v Visitor)
}
// Visitor 接口:为每种具体元素类型定义一个访问方法
// 如果有更多元素类型,这里需要扩展
type Visitor interface {
VisitCircle(c *Circle)
VisitSquare(s *Square)
}
// Concrete Elements
type Circle struct {
Radius float64
}
func (c *Circle) Accept(v Visitor) {
v.VisitCircle(c)
}
type Square struct {
Side float64
}
func (s *Square) Accept(v Visitor) {
v.VisitSquare(s)
}
// Concrete Visitors
type AreaCalculator struct {
TotalArea float64
}
func (ac *AreaCalculator) VisitCircle(c *Circle) {
ac.TotalArea += math.Pi * c.Radius * c.Radius
}
func (ac *AreaCalculator) VisitSquare(s *Square) {
ac.TotalArea += s.Side * s.Side
}
type JSONExporter struct {
Output strings.Builder // 使用strings.Builder更高效
}
func (je *JSONExporter) VisitCircle(c *Circle) {
je.Output.WriteString(fmt.Sprintf(`{"type": "circle", "radius": %.2f},`, c.Radius))
}
func (je *JSONExporter) VisitSquare(s *Square) {
je.Output.WriteString(fmt.Sprintf(`{"type": "square", "side": %.2f},`, s.Side))
}
func main() {
elements := []Element{
&Circle{Radius: 5},
&Square{Side: 10},
&Circle{Radius: 3},
}
fmt.Println("--- 计算总面积 ---")
areaCalc := &AreaCalculator{}
for _, elem := range elements {
elem.Accept(areaCalc)
}
fmt.Printf("总面积: %.2f\n", areaCalc.TotalArea)
fmt.Println("\n--- 导出为 JSON ---")
jsonExp := &JSONExporter{}
jsonExp.Output.WriteString("[") // 开始JSON数组
for _, elem := range elements {
elem.Accept(jsonExp)
}
// 移除末尾逗号(如果有),然后关闭数组
finalOutput := jsonExp.Output.String()
if len(finalOutput) > 1 && finalOutput[len(finalOutput以上就是Golang访问者模式操作对象结构实践的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号