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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章