Visitor模式定义
首先,kubectl
主要是用来处理 Info
结构体,下面是相关的定义:
type VisitorFunc func(*Info, error) error
type Visitor interface {
Visit(VisitorFunc) error
}
type Info struct {
Namespace string
Name string
OtherThings string
}
func (info *Info) Visit(fn VisitorFunc) error {
return fn(info, nil)
}
我们可以看到,
- 有一个
VisitorFunc
的函数类型的定义 - 一个
Visitor
的接口,其中需要Visit(VisitorFunc) error
的方法(这就像是我们上面那个例子的Shape
) - 最后,为
Info
实现Visitor
接口中的Visit()
方法,实现就是直接调用传进来的方法(与前面的例子相仿)
我们再来定义几种不同类型的 Visitor。
Name Visitor
这个Visitor 主要是用来访问 Info
结构中的 Name
和 NameSpace
成员
type NameVisitor struct {
visitor Visitor
}
func (v NameVisitor) Visit(fn VisitorFunc) error {
return v.visitor.Visit(func(info *Info, err error) error {
fmt.Println("NameVisitor() before call function")
err = fn(info, err)
if err == nil {
fmt.Printf("==> Name=%s, NameSpace=%s\n", info.Name, info.Namespace)
}
fmt.Println("NameVisitor() after call function")
return err
})
}
我们可以看到,上面的代码:
- 声明了一个
NameVisitor
的结构体,这个结构体里有一个Visitor
接口成员,这里意味着多态。 - 在实现
Visit()
方法时,其调用了自己结构体内的那个Visitor
的Visitor()
方法,这其实是一种修饰器的模式,用另一个Visitor修饰了自己(关于修饰器模式,参看《Go编程模式:修饰器》)
Other Visitor
这个Visitor主要用来访问 Info
结构中的 OtherThings
成员
type OtherThingsVisitor struct {
visitor Visitor
}
func (v OtherThingsVisitor) Visit(fn VisitorFunc) error {
return v.visitor.Visit(func(info *Info, err error) error {
fmt.Println("OtherThingsVisitor() before call function")
err = fn(info, err)
if err == nil {
fmt.Printf("==> OtherThings=%s\n", info.OtherThings)
}
fmt.Println("OtherThingsVisitor() after call function")
return err
})
}