更新於 2023/08/23閱讀時間約 3 分鐘

Golang - Design Pattern #6: 裝飾者模式 (Decorator)

raw-image


裝飾者模式:像玩樂高一樣組合你的程式!

你還記得小時候玩的樂高嗎?一塊一塊的組裝起來,每塊都增加了更多的功能。裝飾者模式也是這樣,給你一種疊加功能的感覺,但卻不會搞亂原有的設計。


深入一點:裝飾者模式究竟是啥?

裝飾者模式是一種結構型模式,它允許你動態地、一層一層地新增職責到物件上。你可以想像成給咖啡加料,今天想加牛奶,明天加糖,後天加摩卡,所有的組合都可以!


拿 Go 來秀一下

先從簡單的咖啡開始:

package main

import "fmt"

type Beverage interface {
Description() string
Cost() float64
}

type Coffee struct{}

func (c *Coffee) Description() string {
return "基本咖啡"
}

func (c *Coffee) Cost() float64 {
return 5.0
}

type MilkDecorator struct {
beverage Beverage
}

func (m *MilkDecorator) Description() string {
return m.beverage.Description() + " + 牛奶"
}

func (m *MilkDecorator) Cost() float64 {
return m.beverage.Cost() + 1.5
}

這邊你可以看到,MilkDecorator 是如何把牛奶加入咖啡的。現在,我們來看如何用回調函數擴展這個功能:

type ExtraFeature func(Beverage) Beverage

func WithCaramel(b Beverage) Beverage {
return &CaramelDecorator{beverage: b}
}

type CaramelDecorator struct {
beverage Beverage
}

func (c *CaramelDecorator) Description() string {
return c.beverage.Description() + " + 焦糖"
}

func (c *CaramelDecorator) Cost() float64 {
return c.beverage.Cost() + 2.0
}

func main() {
coffee := &Coffee{}
fmt.Println(coffee.Description(), "$", coffee.Cost())

// 使用裝飾者加牛奶
milkCoffee := &MilkDecorator{beverage: coffee}
fmt.Println(milkCoffee.Description(), "$", milkCoffee.Cost())

// 使用回調函數加焦糖
caramelCoffee := WithCaramel(coffee)
fmt.Println(caramelCoffee.Description(), "$", caramelCoffee.Cost())
}

看到了嗎?現在,只要透過回調函數,就能輕鬆地把焦糖功能加到咖啡上!


總結

裝飾者模式就像樂高,一塊一塊組裝,同時確保每塊都有其功能。在程式裡,這意味著我們不會修改原有的代碼,但仍然可以輕鬆地新增新功能。這也像是我們生活中的習慣,一層一層地疊加,構建出豐富多彩的人生。所以,下次寫代碼時,不妨想想裝飾者模式,看看它能為你帶來哪些驚喜!

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.