定义一系列算法,并将每种算法分别放入独立的类中,以使算法的对象能够相互替换。
上下文(Context)维护指向具体策略的引用,且仅通过策略接口与该对象进行交流。
策略(Strategy)接口是所有具体策略的通用接口,它声明了一个上下文用于执行策略的方法。
具体策略(Concrete Strategies)实现了上下文所用算法的各种不同变体。
当上下文需要运行算法时,它会在其已连接的策略对象上调用执行方法。上下文不清楚其所涉及的策略类型与算法的执行方式。
客户端(Client)会创建一个特定策略对象并将其传递给上下文。上下文则会提供一个设置器以便客户端在运行时替换相关联的策略。
构建内存缓存的情形。
// evictionAlgo.go: 策略接口
package main
type EvictionAlgo interface {
evict(c *Cache)
}
// fifo.go: 具体策略
package main
import "fmt"
type Fifo struct {
}
func (l *Fifo) evict(c *Cache) {
fmt.Println("Evicting by fifo strtegy")
}
// lru.go: 具体策略
package main
import "fmt"
type Lru struct {
}
func (l *Lru) evict(c *Cache) {
fmt.Println("Evicting by lru strtegy")
}
// lfu.go: 具体策略
package main
import "fmt"
type Lfu struct {
}
func (l *Lfu) evict(c *Cache) {
fmt.Println("Evicting by lfu strtegy")
}
// cache.go: context
package main
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--
}
// main.go 客户端
package main
func main() {
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")
}
output:
Evicting by lfu strtegy
Evicting by lru strtegy
Evicting by fifo strtegy