访问者模式通过分离操作与数据结构,使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 mainimport ( "fmt" "math" "strings" // 用于处理JSON输出的逗号)// Element 接口:定义了一个接受访问者的方法type Element interface { Accept(v Visitor)}// Visitor 接口:为每种具体元素类型定义一个访问方法// 如果有更多元素类型,这里需要扩展type Visitor interface { VisitCircle(c *Circle) VisitSquare(s *Square)}// Concrete Elementstype 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 Visitorstype 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("总面积: %.2fn", 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访问者模式操作对象结构实践的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1404994.html
微信扫一扫
支付宝扫一扫