访问者(Visitor)模式是一种行为型设计模式。通过访客模式可以为类添加方法而不需要对其做任何调整。
通俗的讲就是在原类上再添加一个方法专门用来接收来访的访问者对象,这个接收访问者的方法中通过调用这个访问者对象的入口方法,将自身实例传入进去,这样访问者就能自己在外部实现它对原类的处理了。
比如,在一个直播间中,直播间对象原始只提供查询创建该直播时的基础信息,如房间名称、简介、公告,主播id等信息,现在有需求是要在管理后台支持查询在线人数,而且后续可能还会不断新增其他需求。
我们不想对原有的直播间对象进行频繁的改动,可以考虑使用访问者模式,将管理后台的请求视作直播访问者,我们为直播间对象新增一个接待直播访问者的方法,直播访问者是一个接口,只要实现直播访问者的接口,任何类型的访问者都可以新增自己想要的操作。
示例代码:
package main
import (
"fmt"
)
// 直播基础信息
type LiveBaseInfo struct {
ID int64
Title string
}
// 直播间内的用户
type User struct {
ID int64
}
// 原始的直播结构
type Live struct {
LiveBaseInfo
OnlineUsers []*User
}
// 原始的直播结构只提供了基础信息查询
func (l *Live) BaseInfo() *LiveBaseInfo {
return &LiveBaseInfo{
ID: l.ID,
Title: l.Title,
}
}
// 我们的访问者接待方法
func (l *Live) Accept(v LiveVistor) {
v.Visit(l)
}
// 直播的访问者接口
type LiveVistor interface {
Visit(*Live)
}
// 管理后台访问者实现
type Manager struct{}
func (m *Manager) Visit(l *Live) {
// 获取在线人数
count := len(l.OnlineUsers)
fmt.Println("online user count:", count)
}
func main() {
live := &Live{
LiveBaseInfo: LiveBaseInfo{
ID: 1,
Title: "my live",
},
OnlineUsers: []*User{
&User{1}, &User{2},
},
}
manager := &Manager{}
live.Accept(manager)
}
运行示例代码,输出结果:
online user count: 2