返回
贴近式设计模式:用Go语言剖析适配器模式及其实际案例
后端
2023-11-18 00:50:11
在本文中,我们将深入探讨为什么写“适配器”模式呢?这一篇关于适配器模式的文章,因为它包含了丰富的场景和实务案例,诸如“监听”平台事件适配数据,调用第三方 接口适配外部数据。最重要的是,我们将通过 Go 语言来剖析适配器模式,并提供详细的实例和案例,让您深入理解如何将抽象和具体的类型一起工作。所以,如果您对设计模式和适配器模式感兴趣,就请继续阅读吧!
1、适配器模式,它是啥?
适配器模式是一种设计模式,它允许两个本来不能兼容的类协同工作。它可以把一个类的借口装扮成别的类的借口,使得本来的两个不能一起工作的类可以一起工作。适配器模式还有助于设计出更松散耦合的系统。
2、适配器模式的优缺点
优 点:
- 可使本来不能在一起工作的两个系统协同工作。
- 有助于设计出更松散耦合的系统。
- 实现了类的适配,便于扩展。
缺 点:
- 系统设计变得复杂,使得系统更难理解。
- 需要预先设计好支持的类型。
- 实现代码比较困难,可能会产生很多适配器。
3、适配器模式的实战案例
场景 1:监听平台事件适配数据
以下代码片段中,EventAdapter
将 Event
的借口装扮成 Message
的借口,使得本来不能一起工作的 Event
和 Message
可以一起工作。
// EventAdapter 实现了Message借口
type EventAdapter struct {
Event event.Event
}
func (adapter *EventAdapter) Handle() {
adapter.Event.DoSomething()
}
// MessageHandler 通过adapter来适配Event
type MessageHandler struct {
Adapter EventAdapter
}
func (handler *MessageHandler) Handle() {
handler.Adapter.Handle()
}
// Event 是被适配者
type Event struct {
DoSomething func()
}
func NewEvent(doSomething func()) Event {
return Event{DoSomething: doSomething}
}
func NewEventAdapter(event Event) EventAdapter {
return EventAdapter{Event: event}
}
func NewMessageHandler(adapter EventAdapter) MessageHandler {
return MessageHandler{Adapter: adapter}
}
// 消息处理函数
func ProcessMessage(handler MessageHandler) {
handler.Handle()
}
func main() {
event := NewEvent(func() {
fmt.Println("事件被处理了")
})
adapter := NewEventAdapter(event)
handler := NewMessageHandler(adapter)
ProcessMessage(handler)
}
场景 2:调用第三方 接口适配外部数据
以下代码片段中,OldSystem
和 NewSystem
的借口不一样,所以不能一起工作。但是,我们可以通过 Adapter
来适配,使得 OldSystem
和 NewSystem
可以一起工作。
// OldSystem 是被适配者
type OldSystem struct {
Name string
}
func (system *OldSystem) PrintName() {
fmt.Println(system.Name)
}
// NewSystem 实现了OldSystem的借口
type NewSystem struct {
Name string
}
func (system *NewSystem) PrintName() {
fmt.Println(system.Name)
}
// ObjectAdapter 对象适配器
type ObjectAdapter struct {
OldSystem OldSystem
}
func (adapter *ObjectAdapter) PrintName() {
adapter.OldSystem.PrintName()
}
// Client 客户端
type Client struct {
System System
}
func (client *Client) PrintName() {
client.System.PrintName()
}
// 创建对象适配器
func NewObjectAdapter(system OldSystem) ObjectAdapter {
return ObjectAdapter{OldSystem: system}
}
// 创建客户端
func NewClient(system System) Client {
return Client{System: system}
}
func main() {
oldSystem := NewOldSystem("老系统")
adapter := NewObjectAdapter(oldSystem)
client := NewClient(adapter)
client.PrintName()
newSystem := NewNewSystem("新系统")
client.System = newSystem
client.PrintName()
}
4、适配器模式的扩展
适配器模式有以下几种扩展:
- 类适配器:这种适配器模式使用继承来适配两个不相容的类。
- 对象适配器:这种适配器模式使用组合来适配两个不相容的类。
- 接口适配器:这种适配器模式使用实现来适配两个不相容的类。
5、适配器模式的使用场景
- 当我们需要将一个类适配到另一个类时,可以使用适配器模式。
- 当我们需要在两个类之间进行转换时,可以使用适配器模式。
- 当我们需要将两个类结合在一起时,可以使用适配器模式。
6、适配器模式与其他设计模式的关系
- 适配器模式与代理模式相似,但代理模式侧重于为一个对象提供一个替代者,而适配器模式侧重于将两个不相容的类结合在一起。
- 适配器模式与门面模式相似,但门面模式侧重于为一组相关类提供一个统一的借口,而适配器模式侧重于将两个不相容的类结合在一起。
- 适配器模式与桥接模式相似,但桥接模式侧重于将抽象和具体的类结合在一起,而适配器模式侧重于将两个不相容的类结合在一起。
7、适配器模式的代码范例
以下代码片段是适配器模式的代码范例:
// TargetInterface 目标借口
type TargetInterface interface {
Request() string
}
// TargetConcreteClass 具体的实现类
type TargetConcreteClass struct {
TargetInterface
}
// adaptee.h 被适配者
type adaptee struct {
SpecificRequest() string
}
// adapter.h 适配者
type adapter struct {
adaptee
}
int main() {
adaptee adaptee1;
adapter adapter1;
adapter1.adaptee = adaptee1;
adapter1.Request(); // output: adaptee1's SpecificRequest
adaptee adaptee2;
adapter adapter2;
adapter2.adaptee = adaptee2;
adapter2.Request(); // output: adaptee2's SpecificRequest
return 0;
}
8、适配器模式的优缺点
优 点:
- 可使本来不能在一起工作的两个系统协同工作。
- 有助于设计出更松散耦合的系统。
- 实现了类的适配,便于扩展。
缺 点:
- 系统设计变得复杂,使得系统更难理解。
- 需要预先设计好支持的类型。
- 实现代码比较困难,可能会产生很多适配器。
9、适配器模式的适用场景
适配器模式适用于以下场景:
- 当我们需要将一个类适配到另一个类时。
- 当我们需要在两个类之间进行转换时。
- 当我们需要将两个类结合在一起时。