[go] 访问者模式

简介: [go] 访问者模式

访问者模式


访问者模式是一种行为设计模式, 它能将算法与其所作用的对象隔离开来。


模型说明


  1. 访问者(Visitor)接口声明了一系列以对象结构的具体元素为参数的访问者方法。如果编程语言支持重载,这些方法的名称可以是相同的,但是其参数一定是不同的。
  2. 具体访问者(Concrete Visitor)会为不同的具体元素类实现相同行为的几个不同版本。
  3. 元素(Element)接口声明了一个方法来“接收”访问者。该方法必须有一个参数被声明为访问者接口类型。
  4. 具体元素(Concrete Element)必须实现接收方法。该方法的目的是根据当前元素类将其调用重定向到相应访问者的方法。请注意,即使元素基类实现了该方法,所有子类都必须对其进行重写并调用访问者对象中的合适方法。
  5. 客户端(Client)通常会作为集合或其他复杂对象(例如一个**组合**树)的代表。客户端通常不知晓所有的具体元素类,因为它们会通过抽象接口与集合中的对象进行交互。


优缺点


1.优点


  • *开闭原则:*你可以引入在不同类对象上执行的新行为,且无需对这些类做出修改。
  • *单一职责原则:*可将同一行为的不同版本移到同一个类中。
  • 访问者对象可以在与各种对象交互时收集一些有用的信息。当你想要遍历一些复杂的对象结构(例如对象树),并在结构中的每个对象上应用访问者时,这些信息可能会有所帮助。


2.缺点


  • 每次在元素层次结构中添加或移除一个类时,你都要更新所有的访问者。
  • 在访问者同某个元素进行交互时,它们可能没有访问元素私有成员变量和方法的必要权限。


使用场景


  • 如果你需要对一个复杂对象结构(例如对象树)中的所有元素执行某些操作,可使用访问者模式。
  • 可使用访问者模式来清理辅助行为的业务逻辑。
  • 当某个行为仅在类层次结构中的一些类中有意义,而在其他类中没有意义时,可使用该模式。


参考代码


shape.go: 元件


package main
type Shape interface {
  getType() string
  accept(Visitor)
}


square.go: 具体元件


package main
type Square struct {
    side int
}
func (s *Square) accept(v Visitor) {
    v.visitForSquare(s)
}
func (s *Square) getType() string {
    return "Square"
}


circle.go: 具体元件


package main
type Circle struct {
    radius int
}
func (c *Circle) accept(v Visitor) {
    v.visitForCircle(c)
}
func (c *Circle) getType() string {
    return "Circle"
}


rectangle.go: 具体元件


package main
type Rectangle struct {
    l int
    b int
}
func (t *Rectangle) accept(v Visitor) {
    v.visitForrectangle(t)
}
func (t *Rectangle) getType() string {
    return "rectangle"
}


visitor.go: 访问者


package main
type Visitor interface {
    visitForSquare(*Square)
    visitForCircle(*Circle)
    visitForRectangle(*Rectangle)
}


areaCalculator.go: 具体访问者


package main
import (
    "fmt"
)
type AreaCalculator struct {
    area int
}
func (a *AreaCalculator) visitForSquare(s *Square) {
    // Calculate area for square.
    // Then assign in to the area instance variable.
    fmt.Println("Calculating area for square")
}
func (a *AreaCalculator) visitForCircle(s *Circle) {
    fmt.Println("Calculating area for circle")
}
func (a *AreaCalculator) visitForRectangle(s *Rectangle) {
    fmt.Println("Calculating area for rectangle")
}


middleCoordinates.go: 具体访问者


package main
import "fmt"
type MiddleCoordinates struct {
    x int
    y int
}
func (a *MiddleCoordinates) visitForSquare(s *Square) {
    // Calculate middle point coordinates for square.
    // Then assign in to the x and y instance variable.
    fmt.Println("Calculating middle point coordinates for square")
}
func (a *MiddleCoordinates) visitForCircle(c *Circle) {
    fmt.Println("Calculating middle point coordinates for circle")
}
func (a *MiddleCoordinates) visitForRectangle(t *Rectangle) {
    fmt.Println("Calculating middle point coordinates for rectangle")
}


main.go: 客户端代码


package main
import "fmt"
func main() {
    square := &Square{side: 2}
    circle := &Circle{radius: 3}
    rectangle := &Rectangle{l: 2, b: 3}
    areaCalculator := &AreaCalculator{}
    square.accept(areaCalculator)
    circle.accept(areaCalculator)
    rectangle.accept(areaCalculator)
    fmt.Println()
    middleCoordinates := &MiddleCoordinates{}
    square.accept(middleCoordinates)
    circle.accept(middleCoordinates)
    rectangle.accept(middleCoordinates)
}


output:


Calculating area for square
Calculating area for circle
Calculating area for rectangle
Calculating middle point coordinates for square
Calculating middle point coordinates for circle
Calculating middle point coordinates for rectangle
相关文章
|
6月前
|
设计模式 Go
[设计模式 Go实现] 行为型~访问者模式
[设计模式 Go实现] 行为型~访问者模式
|
设计模式 Kubernetes 监控
Go编程模式 - 8-装饰、管道和访问者模式
装饰、管道和访问者模式的使用频率不高,但在特定场景下会显得很酷
34 0
|
设计模式 算法 编译器
Go语言实现设计模式之访问者模式
本文将详细介绍Go语言中的访问者模式的概念、用途和实现方法。访问者模式是一种行为型设计模式,它允许你将算法从对象结构中分离出来,从而使算法可以独立于对象而变化。我们将通过开发中的示例和生活中的场景来说明访问者模式的应用场景,并给出相应的代码示例和输出结果。
155 1
|
设计模式 算法 Go
Go的访问者模式
访问者模式是一种行为设计模式,它允许在不修改现有类的情况下向现有类层次结构中添加新操作。它通过引入一个独立的访问者对象,将算法与对象分离。
53 0
|
设计模式 存储 算法
Go设计模式(24)-访问者模式
访问者模式理解比较困难。可以认为对象开了一扇门,用来接收访问者,然后访问者便可在对象内部操作对象。简单来说,对象对访问者进行了授权。这样做能够实现对象和操作的解耦,职责更加单一。对象只管理自身,操作功能安置在访问者中。
|
7天前
|
存储 前端开发 Go
Go语言中的数组
在 Go 语言中,数组是一种固定长度的、相同类型元素的序列。数组声明时长度已确定,不可改变,支持多种初始化方式,如使用 `var` 关键字、短变量声明、省略号 `...` 推断长度等。数组内存布局连续,可通过索引高效访问。遍历数组常用 `for` 循环和 `range` 关键字。
|
9天前
|
Go 调度 开发者
Go语言中的并发编程:深入理解与实践###
探索Go语言在并发编程中的独特优势,揭秘其高效实现的底层机制。本文通过实例和分析,引导读者从基础到进阶,掌握Goroutines、Channels等核心概念,提升并发处理能力。 ###
|
5天前
|
存储 安全 算法
Go语言是如何支持多线程的
【10月更文挑战第21】Go语言是如何支持多线程的
101 72
|
5天前
|
安全 大数据 Go
介绍一下Go语言的并发模型
【10月更文挑战第21】介绍一下Go语言的并发模型
24 14
|
4天前
|
安全 Go 开发者
go语言并发模型
【10月更文挑战第16天】
18 8