策略模式是什麼 策略模式是一種行為設計模式, 它能讓你定義一系列演算法, 並將每種演算法分別放入獨立的類中, 以使演算法的對象能夠相互替換。 為什麼用策略模式 當你想使用對象中各種不同的演算法變體,並希望能在運行時切換演算法時,可使用策略模式。策略模式讓你能將不同行為抽取到一個獨立類層次結構中, 並將原始類組 ...
策略模式是什麼
策略模式是一種行為設計模式, 它能讓你定義一系列演算法, 並將每種演算法分別放入獨立的類中, 以使演算法的對象能夠相互替換。
為什麼用策略模式
當你想使用對象中各種不同的演算法變體,並希望能在運行時切換演算法時,可使用策略模式。策略模式讓你能將不同行為抽取到一個獨立類層次結構中, 並將原始類組合成同一個, 從而減少重覆代碼。策略模式讓你在有多種演算法相似的情況下,減少使用 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")
}
優點
- 演算法多樣性,且具備自由切換功能。
- 你可以將演算法的實現和使用演算法的代碼隔離開來。
- 開閉原則。 你無需對上下文進行修改就能夠引入新的策略。
缺點
- 策略類數量增多,且客戶端必須知曉策略間的不同以便選擇合適的策略。