结构型之代理模式
百里守约学编程
于 2022-09-20 23:48:12 发布
87
收藏
分类专栏:
# go设计模式
文章标签:
代理模式
golang
设计模式
12 篇文章
0 订阅
package proxy
import (
"log"
"time"
)
// IUser IUser
type IUser interface {
Login(username, password string) error
}
// User 用户
type User struct {
}
// Login 用户登录
func (u *User) Login(username, password string) error {
// 不实现细节
return nil
}
// UserProxy 代理类,包含了原始类,并且和原始类实现了相同接口IUser
type UserProxy struct {
user *User
}
// NewUserProxy NewUserProxy
func NewUserProxy(user *User) *UserProxy {
return &UserProxy{
user: user,
}
}
// Login 登录,和 user 实现相同的接口
func (p *UserProxy) Login(username, password string) error {
// before 这里可能会有一些统计的逻辑
start := time.Now()
// 这里是原有的业务逻辑
if err := p.user.Login(username, password); err != nil {
return err
}
// after 这里可能也有一些监控统计的逻辑
log.Printf("user login cost time: %s", time.Now().Sub(start))
return nil
}
// 代理模式:代理模式在不改变原始类接口的条件下,为原始类定义一个代理类,主要目的是控制访问,而非加强功能,这是它跟装饰器模式最大的不同。
package main
// 场景举例:为 UserController 的 register 和 login 方法增加 metrics 打点
// 用户类,业务中用到的实体类
type UserVo struct{}
// 抽象接口,在业务代码中使用接口
type IUserController interface {
login(telephone, password string) UserVo
register(telephone, password string) UserVo
}
// UserController 类,被代理类,处理实际业务
type UserController struct{}
func (uc UserController) register(telephone, password string) UserVo {
// ... register 逻辑 ...
return UserVo{}
}
func (uc UserController) login(telephone, password string) UserVo {
// ... login 逻辑 ...
return UserVo{}
}
// metrics 类
type MetricsCollector struct{}
func (ms MetricsCollector) recordRequest() {}
func NewMetricsCollector() MetricsCollector {
return MetricsCollector{}
}
// UserController的代理类,组合其他类对UserController类相关功能增强
type UserControllerProxy struct {
userController UserController
metricsCollector MetricsCollector
}
func NewUserControllerProxy(userController UserController) UserControllerProxy {
return UserControllerProxy{
userController: userController,
metricsCollector: NewMetricsCollector(),
}
}
// 需要和被代理类实现相同接口,这样才可以把代理类传给接口,然后使用接口,感觉上就像和在使用被代理类一样,实际已经对功能进行了增强
func (ucp UserControllerProxy) register(telephone, password string) UserVo {
userVo := ucp.userController.register(telephone, password)
ucp.metricsCollector.recordRequest()
return userVo
}
func (ucp UserControllerProxy) login(telephone, password string) UserVo {
userVo := ucp.userController.login(telephone, password)
ucp.metricsCollector.recordRequest()
return userVo
}