行为型:五. 策略模式

策略模式是什么

策略模式是一种行为设计模式, 它能让你定义一系列算法, 并将每种算法分别放入独立的类中, 以使算法的对象能够相互替换。

为什么用策略模式

当你想使用对象中各种不同的算法变体,并希望能在运行时切换算法时,可使用策略模式。策略模式让你能将不同行为抽取到一个独立类层次结构中, 并将原始类组合成同一个, 从而减少重复代码。策略模式让你在有多种算法相似的情况下,减少使用 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. 策略类数量增多,且客户端必须知晓策略间的不同以便选择合适的策略。
posted @ 2022-04-17 17:04  EthanWell  阅读(142)  评论(0编辑  收藏  举报