DAY 20:Adapter Pattern,统一不同产品的介面

Creational 建立相关的 patterns 已经告一段落,接下来要进入 Structural 结构模式相关的 patterns,主要目的在设计出低耦合的物件关系,会以 Adapter Pattern 作为开头。

什麽是 Adapter Pattern?

将不同产品不一样的使用方式统一,让使用者可以用统一的方式使用不同产品

市面上有很多不同的 usb 接口,比如 type-a、type-c、micro b 等等,如果我的电脑只支援 type-a 的接口,那就需要一个adapter(转换器),将 type-c、micro b不同的接口转换成统一的。

在写 code 也是一样,系统建构时,如果有多个不同的套件,处理的情境相同,但方法名称不同,建议以 Adapter Pattern 来实作,除了可以弹性的替换套件,也可以避免系统被套件绑定。

什麽是系统被套件绑定?就好像电脑所有的接口都插着 type-a 的设备,而从来不用 adapter,如果有天需使用 type-c 的设备,那除了把插口拔除换成 adapter 别无他法,那如果我们事先就是用 adater 插着电脑,未来要用 type-c 的设备就不需要拔除的这一段(即更改实作)

UML 图:

图中AdapteeA{}AdapteeB{}都有各自的方法,如果 user 要使用他们,必须要有一个统一规范,即是Target interface,AdapterA{}AdapterB{}遵循着规范将AdapteeA{}AdapteeB{}各自的方法转换成Target.methodForUser()方法给 user 使用。

问题情境

使用者买了一个格斗游戏大摇,这个大摇可供 PS5 与 Switch 两种不同的晶片使用,厂商在讯号传递上,需设计一个 adapter 转换器,将大摇的指令可套用在不同的装置上。

解决方式

UML 图如下:

相关的 code 在Github - go-design-patterns

code 如下:

package main

import "fmt"

type SignalHandler interface {
	ClickButton()
}

type PS5 struct{}

func (_ PS5) ClickPS5Button() {
	fmt.Println("click ps5 button")
}

type PS5Adapter struct {
	ps5Machine *PS5
}

func (p PS5Adapter) ClickButton() {
	p.ps5Machine.ClickPS5Button()
}

type Switch struct{}

func (_ Switch) ClickSwitchButton() {
	fmt.Println("click switch button")
}

type SwitchAdapter struct {
	switchMachine *Switch
}

func (p SwitchAdapter) ClickButton() {
	p.switchMachine.ClickSwitchButton()
}

func CreateSignalHandler(platform string) SignalHandler {
	var signalHandler SignalHandler
	switch platform {
	case "ps5":
		signalHandler = PS5Adapter{
			ps5Machine: &PS5{},
		}
	case "switch":
		signalHandler = SwitchAdapter{
			switchMachine: &Switch{},
		}
	}
	return signalHandler
}

func main() {
	signalHandler := CreateSignalHandler("ps5")
	signalHandler.ClickButton()
}

由於PS5{}Switch{}各自点选按钮的方式不同,所以设计了PS5Adapter{}SwitchApater{}并依照SignalHandlerinterface 将功能转换实作至ClickButton(),使用者由於只依赖SignalHandlerinterface,不需理解实际PS5{}Switch{}的点选按钮的方式,只需选择平台後创建好signalHandler,并点选即可。


<<:  Day 18 - custom hook

>>:  <Day18>什麽是K棒?如何用API取得历史K棒资料?

10.MYSQL运算子

每一种语言都有自己运算的符号,SQL也不例外,下面帮大家整理了一些常用的一些运算子,这些运算子会在条...

Day 16 - Apply

到目前为止我们已经知道了 Functor 可以将 effect 跟 pure function 进行...

Day17 在React 中使用Material icons

在React中可以插入Material icon组件使用,步骤如下: Material icons网...

Day-30: 设计转工程师这趟旅程,一些感言

从刚开始看程序码总觉得他们是蚯蚓, 我终於找到一件比做设计还难的事, 当然学习的过程, 没有我想像中...

测试网路两端点频宽效能AB甲乙地,电脑对电脑,网路频宽,iperf jperf

测试网路两端点频宽效能AB甲乙地,电脑对电脑,网路频宽,iperf jperf 工程师常用的应该是 ...