Golang学习笔记_29------抽象工厂模式
Golang学习笔记_30------建造者模式
Golang学习笔记_31------原型模式
文章目录
一、核心概念
定义:将一个类的接口转换成客户端期望的另一个接口,使原本因接口不兼容而无法协同工作的类能一起工作。
核心比喻:类似于电源插头转换器,让美标插头能在欧标插座上使用。
双重角色:
- 接口转换器:解决新旧组件接口不兼容问题
- 包装器:通过包装已有对象提供新接口
二、模式结构

plantuml
@startuml
class Target {
+Request()
}
class Adaptee {
+SpecificRequest()
}
class Adapter {
-adaptee: Adaptee
+Request()
}
Target <|-- Adapter
Adapter o-- Adaptee
note right of Adaptee: 需要被适配的现有类
note left of Target: 客户端期望的接口
@enduml
三、模式特点
优点:
- 兼容性:解决接口不兼容问题,提高系统扩展性
- 复用性:无需修改现有代码即可复用遗留系统
- 透明性:对客户端隐藏适配过程
- 开闭原则:通过新增适配器类实现扩展,而非修改已有代码
缺点:
- 复杂度增加:过多适配器会降低代码可读性
- 性能损耗:多层包装可能带来调用链增长(通常可忽略)
- 设计妥协:可能掩盖接口设计不合理的问题
四、实现方式对比
类型 | 类适配器 | 对象适配器 |
---|---|---|
实现方式 | 多重继承(Go不支持) | 组合 |
灵活性 | 适配特定类 | 适配类及其子类 |
代码侵入性 | 需要修改适配器继承关系 | 无侵入 |
Go适用性 | 不可用 | 推荐方式 |
五、适用场景
- 系统整合:对接第三方库/服务时接口不匹配
- 版本升级:新旧系统兼容过渡
- 接口标准化:统一多个相似功能但接口不同的组件
- 跨平台开发:不同平台API的适配封装
- 测试驱动:创建测试替身(Test Double)
六、与其他模式的对比
1. 与装饰器模式
- 相同:都使用包装技术
- 差异 :
- 适配器:改变被包装对象的接口
- 装饰器:增强接口功能,不改变接口
2. 与外观模式
- 相同:都是包装已有对象
- 差异 :
- 适配器:解决单个组件的接口转换
- 外观:简化复杂子系统的接口
3. 与创建型模式(工厂/原型)
- 关注点 :
- 适配器:接口转换(结构型模式)
- 创建型模式:对象创建机制
- 协同使用:常与抽象工厂结合,创建适配器实例
七、Go实现示例
go
package adapter_demo
import (
"fmt"
)
// 旧接口
type OldLogger interface {
oldLogInfo(message string, level string)
}
// 目标接口(新日志)
type Target interface {
newLogInfo(message string)
}
// 源接口(旧日志)
type oldLogger struct {
Message string
Level string
}
func (ol *oldLogger) oldLogInfo(message string, level string) {
fmt.Println("old Logger: " + message)
fmt.Println("old Logger: " + level)
}
func (l *oldLogger) newLogInfo(message string) {
fmt.Println("new Logger: " + message)
fmt.Println("new Logger: " + l.Level)
}
// 适配器
type LoggerAdapter struct {
legacyLogger *oldLogger
}
func (la *LoggerAdapter) newLogInfo(message string) {
la.legacyLogger.newLogInfo(message)
}
func test() {
newLogger := &LoggerAdapter{
legacyLogger: &oldLogger{
Message: "",
Level: "INFO",
},
}
newLogger.newLogInfo("Hello, World!")
oldLogger := &oldLogger{}
oldLogger.oldLogInfo("Hello, World!", "INFO")
}
输出结果
=== RUN Test_test
new Logger: Hello, World!
new Logger: INFO
old Logger: Hello, World!
old Logger: INFO
--- PASS: Test_test (0.00s)
PASS
八、最佳实践建议
- 优先使用组合:Go推荐对象适配器实现
- 接口最小化:保持目标接口简洁
- 双向适配:需要时实现双向接口转换
- 适配器注册:结合工厂模式管理适配器实例
- 性能监控:关键路径注意多层适配带来的性能影响
通过适配器模式,我们能在保持系统架构整洁的同时,有效整合新旧组件,是应对系统演进和第三方集成的利器。实际应用中需权衡使用场景,避免过度设计。