设计模式学习-使用go实现代理模式
- 代理模式
- 定义
- 优点
- 缺点
- 应用场景
- 代码实现
- 参考
定义:为其对象提供一种代理以控制这个对象的访问。通俗点讲就是它在不改变原始类(或叫被代理类)代码的情况下,通过引入代理类来给原始类附加功能。
来点通俗的理解:
比如我们买火车票,除了火车站,很多代售点也是可以买的,代售点的作用就是代理模式
优点
1、代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;
2、代理对象可以扩展目标对象的功能;
【设计模式学习-使用go实现代理模式】3、代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度,增加了程序的可扩展性;
缺点
1、代理模式会造成系统设计中类的数量增加;
2、在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
3、增加了系统的复杂度;
应用场景
- 1、业务系统的非功能性需求开发
- 2、代理模式在RPC中的应用
GoF的《设计模式》一书中把它称作远程代理。通过远程代理,将网络通信、数据编解码等细节隐藏起来。客户端使用RPC服务就像使用本地函数一样,RPC服务的开发者也只需要开发业务逻辑,就像开发本地使用的函数一样,不需要关注跟客户端的交互细节。
- 3、代理模式在缓存中的应用
简单的做法就是接口写两个,一个支持缓存的一个不支持缓存,但是这样我们的代码就有些臃肿了。
可以使用代理模式中的动态代理。举个栗子:
如果是基于Spring框架来开发的话,那就可以在AOP切面中完成接口缓存的功能。在应用启动的时候,我们从配置文件中加载需要支持缓存的接口,以及相应的缓存策略(比如过期时间)等。当请求到来的时候,我们在AOP切面中拦截请求,如果请求中带有支持缓存的字段(比如http://…?..&cached=true),我们便从缓存(内存缓存或者Redis缓存等)中获取数据直接返回。
代码实现
这里借助于大话设计模式中的追女孩的栗子:
小明喜欢小红,但是害羞不好意思出面,所以拜托好朋友,小张,出面给小红送礼物。
小明是追求者,小张就是小明的中间人,也就是代理。
type GiveGift interface {
GiveDolls() string
GiveFlowers() string
GiveChocolate() string
}// 追求者
type Pursuit struct {
GirlName string
}func NewGirl(name string) *Pursuit {
return &Pursuit{
GirlName: name,
}
}func (ps *Pursuit) GiveDolls() string {
return fmt.Sprintf("%s-送你娃娃", ps.GirlName)
}func (ps *Pursuit) GiveFlowers() string {
return fmt.Sprintf("%s-送你漂亮的鲜花", ps.GirlName)
}func (ps *Pursuit) GiveChocolate() string {
return fmt.Sprintf("%s-送你巧克力", ps.GirlName)
}// 代理也就是中间人
type Proxy struct {
Pursuit
}func NewProxy(name string) *Pursuit {
return NewGirl(name)
}func (pr *Proxy) GiveDolls() string {
return pr.GiveDolls()
}func (pr *Proxy) GiveFlowers() string {
return pr.GiveFlowers()
}func (pr *Proxy) GiveChocolate() string {
return pr.GiveChocolate()
}
最后放上一张结构图
文章图片
参考
【文中代码】https://github.com/boilingfrog/design-pattern-learning/tree/master/代理模式
【大话设计模式】https://book.douban.com/subject/2334288/
【极客时间】https://time.geekbang.org/column/intro/100039001
【代理模式】https://boilingfrog.github.io/2021/11/08/使用go实现代理模式/
推荐阅读
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- 继续努力,自主学习家庭Day135(20181015)
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息
- 一起来学习C语言的字符串转换函数
- 定制一套英文学习方案
- 漫画初学者如何学习漫画背景的透视画法(这篇教程请收藏好了!)