shigen
坚持更新文章的博客写手,擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长,分享认知,留住感动。 个人IP:shigen
最近在学习的时候,突然看到了代理模式。一看就很熟悉,因为在spring中大量用到了代理模式。那接下来将结合查询到的资料和代码,分享一下代理模式的分类和实现,以及golang版本的。
先来看下代理模式的类图,拒绝乱七八糟的文字:

很简单,就是在一个接口的实现类方法处理逻辑中执行其他的逻辑。一分析,重点来了!如何获得接口实现类方法。
静态代理
很简单的一种方式就是我再写一个类,直接把原有的方法调用一遍,不同的是我现在混杂了新逻辑,三方使用的话,也是调用我的新代码逻辑。
相信接下来的代码大家一看就明白,我就直接贴上代码了:
java实现

同样我们改造一下,就是go的实现:
go版本
import "fmt"
// Subject 接口定义了需要被代理的对象的方法
type Subject interface {
Request() string
}
// RealSubject 是需要被代理的对象
type RealSubject struct{}
func (r *RealSubject) Request() string {
return "RealSubject: 处理请求"
}
// Proxy 是代理对象,它包含了一个指向 RealSubject 的引用
type Proxy struct {
realSubject *RealSubject
}
func (p *Proxy) Request() string {
// 在这里可以进行一些额外的操作,例如鉴权、日志等
result := "Proxy: 转发请求到 RealSubjectn"
if p.realSubject == nil {
p.realSubject = &RealSubject{}
}
result += " " + p.realSubject.Request()
return result
}
// 使用代理模式来使用 RealSubject 对象
func main() {
// proxy := &Proxy{}
// fmt.Println(proxy.Request())
realSubject := &RealSubject{}
fmt.Println(realSubject.Request())
}
注:代码和文章参考:
• 详解设计模式:代理模式[1]
• golang代理模式[2]
动态代理
官方一点的话术是这样的:由于静态代理只能够对一种类型(接口)进行代理,如果想要对多种类型进行代理的话就需要创建多个代理类,为了弥补了静态代理的不足,从而出现了动态代理,使用反射技术实现。
我直接表示看不懂,直呼看不懂。
来点简单的,我直接放代码吧:

关键点在于我的Proxyfactory
:
public class ProxyFactory {
public <T> SmsService getProxyObject(T target) {
/**
* ClassLoader loader, 类加载器,加载代理类
* Class<?>[] interfaces, 真实对象实现接口
* InvocationHandler h 代理对象处理的函数
*/
if (target instanceof SmsService) {
return (SmsService) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
System.out.println("开始代理");
Object result = method.invoke(target, objects);
System.out.println("代理结束");
return result;
}
});
} else {
throw new IllegalArgumentException("Target object must implement the specified interface");
}
}
}
函数的参数target
就是需要代理的对象。这里可以封装成一个统一的工具类,先不做展示了。
代码的调用方面:
public class MainMethod {
public static void main(String[] args) {
// 生成新对象
PhoneSmsService phoneSmsService = new PhoneSmsService();
PcSmsService pcSmsService = new PcSmsService();
ProxyFactory proxyFactory = new ProxyFactory();
SmsService PhoneProxyObject = proxyFactory.getProxyObject(phoneSmsService);
SmsService pcProxyObject = proxyFactory.getProxyObject(pcSmsService);
PhoneProxyObject.send();
pcProxyObject.send();
}
}
运行结果:

所以对比之下,动态代理的优点就很明显了:
-
1. 简化开发:相比静态代理,动态代理可以减少重复代码;
-
2. 更灵活:动态代理可以在运行时动态地创建代理对象,可以应用于更广泛的场景。
在此,设计模式的学习+1。
与shigen一起,每天不一样!
引用链接
[1]
详解设计模式:代理模式: https://cloud.tencent.com/developer/article/2183987[2]
golang代理模式: https://learnku.com/docs/go-patterns/1.0.0/dai-li-mo-shi-proxy-pattern/14753
原文始发于微信公众号(shigen):设计模式——代理模式
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/225851.html