1. 程式人生 > 其它 >行為型:五. 策略模式

行為型:五. 策略模式

策略模式是什麼

策略模式是一種行為設計模式, 它能讓你定義一系列演算法, 並將每種演算法分別放入獨立的類中, 以使演算法的物件能夠相互替換。

為什麼用策略模式

當你想使用物件中各種不同的演算法變體,並希望能在執行時切換演算法時,可使用策略模式。策略模式讓你能將不同行為抽取到一個獨立類層次結構中, 並將原始類組合成同一個, 從而減少重複程式碼。策略模式讓你在有多種演算法相似的情況下,減少使用 if...else 或 switch...case 所帶來的複雜性和臃腫性。

策略模式怎麼實現

這裡是以構建快取的形式來舉例,當快取達到最大限制時就要啟動快取淘汰演算法。常用的演算法有:

  1. 最少最近使用 (LRU): 移除最近使用最少的一條條目。
  2. 先進先出 (FIFO): 移除最早建立的條目。
  3. 最少使用 (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")
}

優點

  1. 演算法多樣性,且具備自由切換功能。
  2. 你可以將演算法的實現和使用演算法的程式碼隔離開來。
  3. 開閉原則。 你無需對上下文進行修改就能夠引入新的策略。

缺點

  1. 策略類數量增多,且客戶端必須知曉策略間的不同以便選擇合適的策略。