Go 代理模式

160 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情

代理模式

代理模式是一种代理模式是一种结构模式,其目的是提供对象的代理或中介来控制其访问。 通常包装一个对象来隐藏它的一些特性。

首先,从一个简单的代码先入手理解代理模式:

type Drive interface{
    Drive()
}

type Car struct{}

func (c *Car) Drive(){
    fmt.Println("Car driven")
}
type Driver struct{
    Name string
}
type CarProxy struct {
    car Car
    driver *Driver
}
func (c *CarProxy) Drive(){
    fmt.Println("Car driver name "+c.driver.Name)
}

func NewCarProxy(driver *Driver) *CarProxy {
    return &CarProxy{Car{},driver}
}

实现一个代理类,代理类返回真正的实体。访问代理对象其实就是通过代理对象访问目标。这样就必须要求代理类实现和目标类相同的方法。这样外部就可以通过控制代理类就能完全的控制目标类。

当然代理类也可以继续扩展一些目标类没有的方法,增加额外的功能。

func main(){
    car := NewCarProxy(&Driver{"司机"})
    car.Drive()
}

这里又使用工厂模式,返回一个代理类对象。然后就可以通过代理类操作目标对象。可以看到代理类中的 Driver() 方法中使用的就是 c.driver.name .因为 Car 对象是作为代理类的一个属性存在。

多增加一个目标类,可以更好的体现出代理类的功能:

type Bus struct{}
type CarProxy struct {
    car Car
    bus Bus
    driver *Driver
}


func NewDriveProxy(type string) {
    if type == "car" {
        return &CarProxy{Car{},driver}
    } else if type == "bus" {
        return &CarProxy{Bus{},driver}
    }
}

这样就可以更清晰的看到代理类的作用,根据不同的类型访问不同的目标对象。对于调用者无需关注底层的实现。

优点和缺点

优点

  • 调用者无需关注目标对象,仅有代理类去控制目标对象
  • 允许调用者不关注目标对象的声明周期
  • 即便目标对象没有设计好或不可用,代理类都会保持工作
  • 符合开闭设计原则

缺点

  • 代理对象和目标对象需要实现相同的接口和方法,多个目标对象的话就会导致有很多的代理类
  • 一旦目标类修改就会影响代理类,“牵一发而动全身”的不好现象
  • 服务响应可能会受到影响,因为会增加执行时间的延迟。

适用场景

代理模式适合用在一些非功能的需求上,比如监控,日志,鉴权等,通过使用代理模式,将业务功能和其非功能的进行解耦。由代理类统一处理。