DAY 21:Bridge Pattern,桥接人间与魔界的次元门

什麽是 Bridge Pattern?

将抽像与实现分离,让彼此变化互不影响

问题情境

PS5 有着 PS5WithCD 与 PS5WithDigital 两个版本

如果使用传统的继承,我们要在 PS5WithCD 与 PS5WithDigital 上新增不同的手把款式,又要再个别新增两个类别,但已问题的本质来说,这是件很奇怪的事情,只是新增不同的手把却要做出新的 PS5。

那如果要再新增不同的手把配不同的 Sony 萤幕,这样又要新增更多的类别,这样就使得「不同的实现影响到了 PS5 这个物件的抽象」,我们需设计一个方式避免这种情形。

解决方式

UML 图如下:

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

code 如下:

package main

type Controller interface {
	MethodA()
	MethodB()
	MethodC()
	MethodD()
}

type ControllerA struct{}

func (c ControllerA) MethodA() {}
func (c ControllerA) MethodB() {}
func (c ControllerA) MethodC() {}
func (c ControllerA) MethodD() {}

type ControllerB struct{}

func (c ControllerB) MethodA() {}
func (c ControllerB) MethodB() {}
func (c ControllerB) MethodC() {}
func (c ControllerB) MethodD() {}

type PS5 interface {
	Start()
	SetController()
	Play()
}

type PS5Machine struct {
	ps5Controller Controller
}

func (p PS5Machine) Start() {
	p.ps5Controller.MethodA()
	p.ps5Controller.MethodB()
}

func (p *PS5Machine) SetController(controller Controller) {
	p.ps5Controller = controller
}

func (p PS5Machine) Play() {
	p.ps5Controller.MethodC()
	p.ps5Controller.MethodD()
}

func main() {
	ps5 := PS5Machine{}
	ps5.Start()
	ps5.SetController(ControllerA{})
	ps5.Play()
	ps5.SetController(ControllerB{})
	ps5.Play()
}

我们将摇杆定义了一个Controllerinterface,而PS5Machine{}实际的实作都是依赖於此 interface,藉由PS5Machine.SetController()来任意变换摇杆,只要符合 interface 的规范即可,不需要为了不同的摇杆而新增新的 struct。


<<:  Day19 不使用JSX开发React的方式

>>:  Swift纯Code之旅 Day24. 「各个TableViewHeader下的Cell显示(1)」

[Day18] 抽象类别

抽象类别 PHP也支援抽象类的和抽象方法,被定义为抽象类的方法不能被实体化,在任何一个类别中, 如果...

#19 Telegram Bot 起手式

今天开始做我们的 Telegram Bot! Telegram Telegram 是一个通讯软件,就...

我们的基因体时代-AI, Data和生物资讯 Day24- 使用tidyverse观念来分析基因资料:plyranges

上一篇我们的基因体时代-AI, Data和生物资讯 Day23- 基因注释资料在Bioconduct...

[27] 30 天从 Swift 学会 Objective-C:Swift friendly 的 Unavailable 与 convenience init

物件导向的设计中,关於建构物件的方式我们成为建构器(constructor),这关系到物件使用的方式...

Ruby on Rails 模组(Module)

如果我有一个小猫类别,我想要这个小猫类别有飞行功能,你会怎麽做? 直接写一个有飞行功能的小鸟类别,然...