今天開始要介紹 Structural patterns。先前的 Creational patterns 著重在如何根據不同的問題建立一個新的物件,而 Structural patterns 則著重在如何連結、組合已經存在的物件來解決問題。
這個模式其實大家相對熟悉,生活當中的各種「轉接頭」其實就是轉接器模式的應用。轉接器最大的目的在於,將兩個「不同介面」的物件組合在一起,譬如
等等。接下來讓我們看一下簡單的例子。
這裡有個 Time
類別,當中的靜態方法 getTime
可以幫我們拿到當下的時間。另外一邊有個 Printer
類別,當中的靜態方法 printWithTitle
會回傳字串給我們。
class Time {
static getTime(): Date {
return new Date()
}
}
class Printer {
static printWithTitle(title: string, data: string): string {
return `${title}: ${data}`
}
}
所以我們今天如果想要先用 Time
獲得當下的時間,緊接著用 Printer
來幫我們「印」出來,所以會是下面這樣
const time = Time.getTime()
Printer.printWithTitle('Now is', time) // error
然而我們很快就會看到錯誤訊息,因為 printWithTitle
本身期待傳入的資料都是字串,但這裡我們卻傳入了一個 Date 物件,所以產生錯誤。
因此我們可以使用一個轉接器,來幫助我們轉換介面。以這裡的例子,我們希望能夠將 Date 轉換成 string,所以轉接器就會長得像下面這樣
class Adaptor {
static dateToString(data: Date): string {
return data.toString()
}
}
使用轉接器過後,我們就可以順利得到結果了
const time = Time.getTime()
Printer.printWithTitle('Now is', Adaptor.dateToString(time))
Now is: Tue Sep 28 2021 11:55:12 GMT+0000 (Coordinated Universal Time)
使用轉接器的優點是,可以讓原本兩個類別都專注在自己的功能上面,不需要去管因為他人使用而造成的介面轉接問題。然而缺點是,如果我們已經很確定使用者是誰,那麼其實我們可以直接轉換成使用者需要的介面,也就不需要額外創造一個新的轉接器來使用。
轉接器模式提供了一個快速解決問題的方案,但在穩定、可期待的使用場景之中,轉接器看起來就沒有那麼必要了。