欢迎大家来到IT世界,在知识的湖畔探索吧!
代理模式(Proxy Pattern)和适配器模式(Adapter Pattern)是两种常用的结构型设计模式,它们在实现上有相似之处(例如都涉及间接引用对象),但设计目的和适用场景完全不同。以下是它们的异同点分析:
相同点
- 间接访问:两者都通过一个中间对象(代理类或适配器类)间接操作目标对象。
- 实现方式:都可能通过组合(持有目标对象的引用)或继承(继承目标类)来实现。
- 结构相似性:从代码结构上看,两者都可能实现相同的接口或继承相同的类。
不同点
|
维度 |
代理模式 |
适配器模式 |
|
设计目的 |
控制对对象的访问(如延迟加载、权限控制、缓存等)。 |
解决接口不兼容问题,使原本不兼容的类能协同工作。 |
|
关注点 |
增强目标对象的功能或访问方式。 |
转换接口形式,不增强功能。 |
|
调用关系 |
代理类和目标类通常实现同一接口,代理直接代表目标对象。 |
适配器类与目标类可能实现不同接口,通过适配器间接调用目标。 |
|
适用场景 |
远程代理、虚拟代理、保护代理、缓存代理等。 |
系统升级时兼容旧接口、整合第三方库等。 |
|
对象创建时机 |
代理可能延迟创建目标对象(如虚拟代理)。 |
适配器通常持有已存在的目标对象。 |
|
代码示例 |
用户通过代理访问数据库,代理添加了权限检查逻辑。 |
将旧的日志接口适配成新系统需要的接口格式。 |
本质区别
- 代理模式:控制访问,强调对目标对象行为的管理或增强(如AOP的拦截)。
- 适配器模式:接口转换,强调解决兼容性问题,不修改原有逻辑。
类比说明
- 代理模式像明星的经纪人:控制外界对明星的访问(如过滤不合理的请求)。
- 适配器模式像电源转换插头:将一种接口(插头类型)转换成另一种接口,使设备能正常工作。
代码示例对比
代理模式
// 接口 type Image interface { display() } // 真实对象 type RealImage struct {} func (r *RealImage) display() { fmt.Println("显示图片") } // 代理 type ProxyImage struct { realImage *RealImage } func (p *ProxyImage)display() { if p.realImage == nil { p.realImage = new RealImage(); } // 在调用真实对象前可以添加预处理 fmt.Println("Proxy: Pre-processing request.") p.realImage.display(); // 在调用真实对象后可以添加后处理 fmt.Println("Proxy: Post-processing request.") }
欢迎大家来到IT世界,在知识的湖畔探索吧!
适配器模式
欢迎大家来到IT世界,在知识的湖畔探索吧!//老接口 type LegacyLogger struct { func log(message string){ fmt.Println("old log:", message) } } // 新接口(系统需要的) type NewLogger interface { log(message string) } type LoggerAdapter struct { oldLogger *LegacyLogger } func (l *loggerAdapter)setOldLogger(oldLogger *LegacyLogger) { l.oldLogger = oldLogger } func (l *loggerAdapter) log(message string) { // 适配 l.oldLogger.log(message) fmt.Println("new log:", message) }
总结
- 如果需要控制或增强对象的行为(如权限、缓存),用代理模式。
- 如果需要解决接口不兼容问题,用适配器模式。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/138067.html