【Go-设计模式】代理模式 详解

shadowLogo

概念:

一个对象 提供 一个替身,以 控制对这个对象的访问
即:通过代理对象访问目标对象
好处是:可以在 目标对象实现的基础上,增强额外的功能操作,即 扩展目标对象 的功能

被代理的对象可以是 远程对象创建开销大的对象需要安全控制的对象

代理模式有不同的形式,主要有三种:

静态代理
动态代理 (JDK 代理、接口代理)

proxy


UML:

uml

  • TargetObject:
    目标对象,基本的处理逻辑
  • ProxyObject:
    代理对象,对目标对象进行封装的处理逻辑

静态代理:

静态代理在使用时,需要定义接口或者父类
被代理对象(即目标对象)代理对象 一起 实现相同的接口 或者是 继承相同父类

  • 优点:
    在不修改目标对象的功能前提下, 能通过代理对象对目标功能扩展
  • 缺点:
    因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类
    一旦接口增加方法,目标对象与代理对象都要维护

动态代理:

动态代理 也叫做 接口代理
代理对象的 生成,是 动态 地在 内存中 构建代理对象


示例:

功能接口:

type ProxyInterface interface {
	Execute() string
}

被代理的对象:

type Model struct{}

func (Model) Execute() string {
	return "real execute"
}

代理对象:

type Proxy struct {
	realModel Model
}

func (this Proxy) Execute() string {
	return "\n执行前" + this.realModel.Execute() + "\n执行后"
}

测试:

package main

import (
	"DemoProject/design/base23"	// 根据自己的项目路径定制
	"fmt"
)

func main() {
	var obj base23.ProxyInterface
	obj = &base23.Proxy{}

	res := obj.Execute()

	fmt.Print(res)
}


几种变形:

  1. 防火墙代理
    内网通过代理穿透防火墙,实现对公网的访问。
  2. 缓存代理
    比如:当请求图片文件等资源时,先到缓存代理取,如果取到资源则 ok,如果取不到资源,再到公网或者数据库取,然后缓存。
  3. 远程代理
    远程对象的本地代表,通过它可以把远程对象当本地对象来调用。远程代理通过网络和真正的远程对象沟通信息。
  4. 同步代理
    主要使用在多线程编程中,完成多线程间同步工作同步代理:主要使用在多线程编程中,完成多线程间同步工作

后记:

在Golang中,因为原生SDK没有提供 动态代理 类供我们生成 动态代理
因此,在本文中,就通过 静态代理,来讲解和实现 代理模式
那么,在上文中,本人也说明了:

静态代理 的 好处是:实现简单
但是相比动态代理,坏处是:如果接口方法更改,那么 代理对象类 和 目标代理类 都要进行手动更改
这是非常难以接受的

看到这里,相信很多同学对于 “Java中的动态代理” 十分怀念
因为 动态代理 无需我们去手动维护 被代理的类、代理类 和 代理接口 之间的关系
但是,相信很多同学也不了解 Java动态代理实现原理

那么,本人来总结下 “Java中的动态代理” 的 底层实现原理

  • 根据手动设置的 invoke逻辑,生成 中间类Class类型
  • 通过反射机制,创建该 Class类型的 对象实例
  • 后续的方法调用,就是调用的 生成的对象实例 的 方法逻辑
    (可以理解为 通过字节码技术,在内存中生成中间类元信息,根据该信息生成对应的实例,该实例就是创建的代理对象)

具体分析,请看其他博主的博文:《Java 动态代理底层实现原理》

posted @ 2021-12-12 23:00  在下右转,有何贵干  阅读(272)  评论(0)    收藏  举报