Golang 设计模式系列5: 桥接模式(Bridge Pattern)

桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。

在桥接模式结构图中包含如下几个角色:
在这里插入图片描述

  • Abstraction(抽象类):用于定义抽象类的接口,它一般是抽象类而不是接口,其中定义了一个 Implementor(实现类接口)类型的对象并可以维护该对象,它与 Implementor 之间具有关联关系,它既可以包含抽象业务方法,也可以包含具体业务方法。

  • RefinedAbstraction(扩充抽象类):扩充由 Abstraction 定义的接口,通常情况下它不再是抽象类而是具体类,它实现了在 Abstraction 中声明的抽象业务方法,在 RefinedAbstraction 中可以调用在 Implementor 中定义的业务方法。

  • Implementor(实现类接口):定义实现类的接口,这个接口不一定要与 Abstraction 的接口完全一致,事实上这两个接口可以完全不同,一般而言,Implementor 接口仅提供基本操作,而 Abstraction 定义的接口可能会做更多更复杂的操作。Implementor 接口对这些基本操作进行了声明,而具体实现交给其子类。通过关联关系,在 Abstraction 中不仅拥有自己的方法,还可以调用到 Implementor 中定义的方法,使用关联关系来替代继承关系。

  • ConcreteImplementor(具体实现类):具体实现 Implementor 接口,在不同的 ConcreteImplementor 中提供基本操作的不同实现,在程序运行时,ConcreteImplementor 对象将替换其父类对象,提供给抽象类具体的业务操作方法。

应用场景

假设我们开了一家咖啡店,用户可以选择不同大小的咖啡,可以选择加奶或者加糖,如果用普通的继承结构会变成如下的样子。
在这里插入图片描述
这时客户要求还想要加蜂蜜的咖啡,有的客户又想要特大号咖啡,随着种类的增加类的总类也在增加,最后会发现我们会有杯子大小种类x配料种类的个数的类。
为了解决会出现如此多类的问题,这里是用桥接模式来简化结构。
在这里插入图片描述
其中ICoffee作为抽象类,提供了OrderCoffee的方法, 并保有一个实现类方法的实例,具体实现方法大杯(LargeCoffee)和小杯(SmallCoffee)分别实现了自己的OrderCoffee方法,配料Sugar和Milk则作为具体实现类被附在抽象类上

具体实现

package bridge

import "fmt"

type ICoffee interface {
	OrderCoffee(count int)
}

type LargeCoffee struct {
	additives ICoffeeAdditives
}

func (l *LargeCoffee) OrderCoffee(count int) {
	fmt.Print("Large Coffee ")
	l.additives.AddAdditives()
	fmt.Println(count, " cup")
}

type SmallCoffee struct {
	additives ICoffeeAdditives
}

func (s *SmallCoffee) OrderCoffee(count int) {
	fmt.Print("Small Coffee ")
	s.additives.AddAdditives()
	fmt.Println(count, "cup")
}

type ICoffeeAdditives interface {
	AddAdditives()
}

type Milk struct{}

func (m *Milk) AddAdditives() {
	fmt.Print("With Milk ")
}

type Sugar struct{}

func (s *Sugar) AddAdditives() {
	fmt.Print("With Sugar ")
}

测试代码

package bridge

import (
	"testing"
)

func TestPrintAPI1(t *testing.T) {
	largeCoffeeMilk := LargeCoffee{
		additives: &Milk{},
	}
	largeCoffeeMilk.OrderCoffee(1)
	smallCoffeeMilk := SmallCoffee{
		additives: &Milk{},
	}
	smallCoffeeMilk.OrderCoffee(1)
	largeCoffeeSugar := LargeCoffee{
		additives: &Sugar{},
	}
	largeCoffeeSugar.OrderCoffee(1)
	smallCoffeeMSugar := SmallCoffee{
		additives: &Sugar{},
	}
	smallCoffeeMSugar.OrderCoffee(1)
}
=== RUN   TestPrintAPI1
Large Coffee With Milk 1  cup
Small Coffee With Milk 1  cup
Large Coffee With Sugar 1  cup
Small Coffee With Sugar 1  cup
--- PASS: TestPrintAPI1 (0.00s)
PASS
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章