适配器模式(Adapter)

适配器模式(Adapter)/包装器模式(Wrapper)

1.意图

将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

2.适用性

以下情况使用Adapter模式

  • 你想使用一个已经存在的类,而它的接口不符合你的需求。
  • 你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
  • (仅适用于对象Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
3.结构

类适配器使用多重继承对一个接口与另一个接口进行匹配,如下图所示。

在这里插入图片描述

对象匹配器依赖于对象组合,如下图所示。

在这里插入图片描述

4.代码
package adapter

import (
	"fmt"
	"testing"
)

/*
# 适配器模式
在计算机编程中,适配器模式(有时候也称包装样式或者包装)
将一个类的接口适配成用户所期待的。一个适配允许通常因为
接口不兼容而不能在一起工作的类工作在一起,做法是将类自
己的接口包裹在一个已存在的类中。

适配器模式用于转换一种接口适配另一种接口。
实际使用中Adaptee一般为接口,并且使用工厂函数生成实例。
在Adapter中匿名组合Adaptee接口,所以Adapter类也拥有
SpecificRequest实例方法,又因为Go语言中非入侵式接口特征,
其实Adapter也适配Adaptee接口。
*/

type Phone struct {
	name string
}

type MicroUsb interface {
	LinkPhone(phone Phone)
}

type microUSBImpl struct {}

func NewMicroUSB()MicroUsb{
	return &microUSBImpl{}
}

func (this *microUSBImpl)LinkPhone(phone Phone){
	fmt.Println("使用MicroUSB连接",phone.name)
}

type USB interface {
	LinkUSBDevice()
}

type usbImpl struct {}

func (*usbImpl)LinkUSBDevice()  {
	fmt.Println("USB设备就绪......")
}

func NewUSB()USB{
	return &usbImpl{}
}


//现在USB设备不能直接连接手机,怎么办?
//弄出一个OTG转接线,这个线就是一个  适配器
type OTG struct {
	USB
}

func (this *OTG) LinkPhone(phone Phone) {
	this.USB.LinkUSBDevice()
	fmt.Println("使用OTG转接......带有MicroUSB接口的线")
	NewMicroUSB().LinkPhone(phone)
}

//创建适配器
func NewOTG(usb USB)MicroUsb{
	return &OTG{
		USB:usb,
	}
}


func TestAdapter(t *testing.T) {
	usb:=NewUSB()
	musb:=NewOTG(usb)
	phone:=Phone{"大哥大"}
	musb.LinkPhone(phone)
}

/*
=== RUN   TestAdapter
USB设备就绪......
使用OTG转接......带有MicroUSB接口的线
使用MicroUSB连接 大哥大
--- PASS: TestAdapter (0.00s)
PASS
*/




// 我们的接口(新接口)——音乐播放
type MusicPlayer interface {
	play(fileType string, fileName string)
}

// 在网上找的已实现好的库 音乐播放
// ( 旧接口)
type ExistPlayer struct {
}

func (*ExistPlayer) playMp3(fileName string) {
	fmt.Println("play mp3 :", fileName)
}
func (*ExistPlayer) playWma(fileName string) {
	fmt.Println("play wma :", fileName)
}

// 适配器
type PlayerAdaptor struct {
	// 持有一个旧接口
	existPlayer ExistPlayer
}

// 实现新接口
func (player *PlayerAdaptor) play(fileType string, fileName string) {
	switch fileType {
	case "mp3":
		player.existPlayer.playMp3(fileName)
	case "wma":
		player.existPlayer.playWma(fileName)
	default:
		fmt.Println("暂时不支持此类型文件播放")
	}
}


func TestPlayer( t *testing.T) {
	player := PlayerAdaptor{}
	player.play("mp3", "死了都要爱")
	player.play("wma", "滴滴")
	player.play("mp4", "复仇者联盟")
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

metabit

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值