行為型:五. 策略模式
阿新 • • 發佈:2022-04-17
策略模式是什麼
策略模式是一種行為設計模式, 它能讓你定義一系列演算法, 並將每種演算法分別放入獨立的類中, 以使演算法的物件能夠相互替換。
為什麼用策略模式
當你想使用物件中各種不同的演算法變體,並希望能在執行時切換演算法時,可使用策略模式。策略模式讓你能將不同行為抽取到一個獨立類層次結構中, 並將原始類組合成同一個, 從而減少重複程式碼。策略模式讓你在有多種演算法相似的情況下,減少使用 if...else 或 switch...case 所帶來的複雜性和臃腫性。
策略模式怎麼實現
這裡是以構建快取的形式來舉例,當快取達到最大限制時就要啟動快取淘汰演算法。常用的演算法有:
- 最少最近使用 (LRU): 移除最近使用最少的一條條目。
- 先進先出 (FIFO): 移除最早建立的條目。
- 最少使用 (LFU): 移除使用頻率最低一條條目。
然後我們可以把每個快取淘汰演算法放入獨立的類中,以便可以相互替換演算法。
cache.go 構建快取
package strategy type cache struct { storage map[string]string evictionAlgo evictionAlgo capacity int maxCapacity int } func initCache(e evictionAlgo) *cache { storage := make(map[string]string) return &cache{ storage: storage, evictionAlgo: e, capacity: 0, maxCapacity: 2, } } func (c *cache) setEvictionAlgo(e evictionAlgo) { c.evictionAlgo = e } func (c *cache) add(key, value string) { if c.capacity == c.maxCapacity { c.evict() } c.capacity++ c.storage[key] = value } func (c *cache) get(key string) { delete(c.storage, key) } func (c *cache) evict() { c.evictionAlgo.evict(c) c.capacity-- }
eviction_algo.go 淘汰演算法
package strategy import "fmt" type evictionAlgo interface { evict(c *cache) } type fifo struct { } func (l *fifo) evict(c *cache) { fmt.Println("Evicting by fifo strtegy") } type lru struct { } func (l *lru) evict(c *cache) { fmt.Println("Evicting by lru strtegy") } type lfu struct { } func (l *lfu) evict(c *cache) { fmt.Println("Evicting by lfu strtegy") }
example.go 客戶端呼叫
package strategy
func Example() {
lfu := &lfu{}
cache := initCache(lfu)
cache.add("a", "1")
cache.add("b", "2")
cache.add("c", "3")
lru := &lru{}
cache.setEvictionAlgo(lru)
cache.add("d", "4")
fifo := &fifo{}
cache.setEvictionAlgo(fifo)
cache.add("e", "5")
}
優點
- 演算法多樣性,且具備自由切換功能。
- 你可以將演算法的實現和使用演算法的程式碼隔離開來。
- 開閉原則。 你無需對上下文進行修改就能夠引入新的策略。
缺點
- 策略類數量增多,且客戶端必須知曉策略間的不同以便選擇合適的策略。