今天的橋接器模式,和昨天的轉接器模式一樣,都是非常常見的模式,可能我們不自覺當中都會使用到。話不多說,我們就先來看例子吧!
這裡有一個 Shape
類別,定義了基本的屬性 name
和 color
。接著我們可以建立 Square
類別,他繼承了 Shape
,在執行細節上,直接將 name
設定為 "square"。
當然我們也可以建立一個 RedSquare
類別,同樣是繼承 Shape
,在執行細節上,直接將 name
設定為 "square"、將 color
設定為 "red"
class Shape {
name: string
color: string
}
class Square extends Shape {
constructor() {
super()
this.name = 'square'
}
}
class RedSquare extends Shape {
constructor() {
super()
this.name = 'triangle'
this.color = 'red'
}
}
到目前為止看起來都很合理
如果現在我們希望增加一個 Triangle
類別,以及為各種 Shape
新增一個顏色,譬如藍色,那麼我們就需要建立
四種類別。如果我們有十種形狀、十種顏色,那麼如果要建立出所有顏色的形狀,那麼就需要建立 100 個新類別,看起來就有點不合理了。這時候該怎麼辦呢?
不如,我們就把形狀和顏色先拆開來處理,然後找一個方法,將兩者連接再一起。
讓我們先來處理顏色的部分。這裡我先建立一個抽象類別 Color
,定義未來各種顏色類別的基本樣貌。接著,我們建立了 Green
和 Blue
類別,用來產生顏色的實例
class Color {
color: string
}
class Green extends Color {
color = 'green'
constructor(){
super()
}
}
class Blue extends Color {
color = 'blue'
constructor(){
super()
}
}
之後,讓我們回頭看看 Shape
這邊。我們同樣有 Shape
這個抽象類別,緊接著建立 Square
和 Triangle
兩個類別。
不過這裡我們要怎麼把形狀跟顏色連接在一起呢?這裡我們在 constructor 當中放入顏色,讓不同形狀的實例能夠具備該有的顏色
class Shape {
name: string
color: string
}
class Square extends Shape {
constructor(color: string) {
super()
this.name = 'square'
this.color = color
}
getDescription(): string {
return `I am the best ${this.color} ${this.name}!`
}
}
class Triangle extends Shape {
constructor(color: string) {
super()
this.name = 'triangle'
this.color = color
}
getDescription(): string {
return `I am a ${this.color} ${this.name}!`
}
}
最後,我們先建立顏色的實例,接著,就可以創造出各種顏色的形狀了!
const green = new Green()
const blue = new Blue()
const greenSquare = new Square(green.color)
const blueSquare = new Square(blue.color)
const greenTriangle = new Triangle(green.color)
const blueTriangle = new Triangle(blue.color)
greenSquare.getDescription() // 'I am the best green square!'
blueSquare.getDescription() // 'I am the best blue square!'
greenTriangle.getDescription() // 'I am a green triangle!'
blueTriangle.getDescription() // 'I am a blue triangle!'
橋接器模式將一個物件當中的不同屬性拆開來處理(譬如這裡的 shape 和 color),讓程式碼具備擴充性。但是如果這些屬性彼此之間高度相關的話,那麼就比較難輕易的實作橋接,或是會讓程式碼本身變得更為複雜。