设计模式-适配器模式
Posted by 付辉 on Sunday, April 7, 2019 共973字
当你眼里只有赚钱的时候,你就永远无法把事情本身给做好,收获的也会很有限,最后可能还赚不到钱。- From Myself
下面的代码是github.com/gin-gonic/gin/binding
中获取Binding
实例的逻辑。我在想:这段代码体现的是什么设计模式呢?写法上肯定是工厂模式,因为它基于不同的contentType
创建返回具体的实例。但从宏观上来看,它算不算一个适配器呢?
func Default(method, contentType string) Binding {
if method == "GET" {
return Form
}
switch contentType {
case MIMEJSON:
return JSON
case MIMEXML, MIMEXML2:
return XML
case MIMEPROTOBUF:
return ProtoBuf
case MIMEMSGPACK, MIMEMSGPACK2:
return MsgPack
default: //case MIMEPOSTForm, MIMEMultipartPOSTForm:
return Form
}
}
Adapter Pattern
适配器模式不仅仅局限于代码设计,在现实世界中也经常会看到。比如苹果手机的转接线,将新的、方形的Lighting
接口适配到旧的、圆孔的耳机上。
Adapter Pattern
主要被用来适配两个不兼容的接口,给两个独立或者不兼容的类提供一个兼容模式,而不需要修改两者内部的具体实现。Adapter Pattern
可以是一个独立的新对象或者新方法,在设计中扮演一个桥梁的作用,或者是对不相互兼容的数据格式进行转换。又或者是重用系统老的既存类,来提供新的功能。
Purpose
适配器主要通过转换数据格式,组合、引用不兼容的对象,最终实现我们期盼的功能。
- 老系统到新系统的业务迁移。新老系统首先在接收数据的格式上不尽相同,其次新系统可能也需要调用老系统的内部实现。
- 重新对对象进行封装,用来提供业务期望的新功能。或者让不兼容的对象可以一起工作。
Design Pattern Diagram
Target
:Client
端调用的新接口。Adapter
:将Adaptee
适配到Target
,实现两者间的转换。Adaptee
:需要去适配的既存接口
Implementation
常见的适配实现主要有两种方式:
- 通过类的继承来实现
- 通过类的组合来实现
很多地方都有提到:组合优于继承。因为组合结构非常灵活,而且没有继承关系中改变既有代码的负面影响。适配器作为一个独立的类,用组合的方式,也更能体现出桥梁的作用。
Verdict
Adapter Pattern
可以用于新老功能的数据结构转换,或者基于既有类来实现额外的功能。如果Target
和Adaptee
功能相似,那么Adapter
可能只需要委托Adaptee
去处理。但如果不相似,我们可能就需要转换两者的数据结构,并组合其他功能类来实现具体的处理逻辑了。
Adapter Pattern
的优势在于:通过引入一个适配类,我们无需去改变已经存在的类或者接口,也有效的限制了代码调整的范围,避免对现有业务造成一些未知的负面影响。
参考文章: