GoLang设计模式16 - 策略模式(行为型)
策略模式是一种行为型设计模式。通过策略模式,可以在运行时修改一个对象的行为。
接下来仍然是通过例子来了解策略模式。比如说内存缓存,这是我们在开发中经常使用的东西,大家应该都有一定的了解,接下来就用内存缓存来说明下如何使用策略模式。
向内存里存东西对于GoLang来说算是比较简单的事情,通过Map就可以做到,不过还是建议创建一个Cache struct来稍稍封装一下。不过我们都知道,内存缓存占用的空间是有上限的。当快达到上限时,就需要清理一下缓存中已有的内容。如下是清理缓存的一些常见的算法:
- LRU(Least Recently Used):清理最近使用的最少的那些缓存数据
- FIFO(First In First Out):清理最早放入缓存的那些数据
- LFU(Least Frequently Used):清理使用频率最低的那部分数据
现在的问题是如何将Cache和清理算法解耦,这样在运行时就可以调整清理缓存的算法了。但也要注意,在添加新的清理算法时,不应该改动Cache。这时候就需要用到策略模式了。策略模式建议为相同业务的各种算法创建一个算法组,然后将每种算法都封装起来,使之有相同的接口,并且不同算法之间可以互换。清理缓存的算法的接口就可以命名为:evictionAlgo。
然后将evictionAlgo接口嵌入Cache中就可以了。
不同于让Cache直接自己继承evictionAlgo接口,现在可以通过evictionAlgo接口来组装不同的清理算法。因为evictionAlgo是一个接口,这样在运行的时候就可以将之赋值为LRU、FIFO或LFU,而不需要对Cache struct做任何调整。
现在捋一下什么时候使用策略模式:
- 当一个对象需要提供不同的行为,而又不想在运行时修改对象时
- 当想在运行时选择不同的行为而又不想写大量的条件语句时
- 当为同一种行为准备了不同的算法时
下面是策略模式的UML类图:

这里是我们当前这个内存缓存案例的UML图:

具体代码如下:
1 type evictionAlgo interface { 2 evict(c *cache) 3 } 4 5 type lru struct { 6 } 7 8 func (l *lru) evict(c *cache) { 9 fmt.Println("Evicting by lru strategy") 10 } 11 12 type fifo struct { 13 } 14 15 func (l *fifo) evict(c *cache) { 16 fmt.Println("Evicting by fifo strategy") 17 } 18 19 type lfu struct { 20 } 21 22 func (l *lfu) evict(c *cache) { 23 fmt.Println("Evicting by lfu strategy") 24 } 25 26 type cache struct { 27 storage map[string]string 28 evictionAlgo evictionAlgo 29 capacity int 30 maxCapacity int 31 } 32 33 func initCache(e evictionAlgo) *cache { 34 storage := make(map[string]string) 35 return &cache{ 36 storage: storage, 37 evictionAlgo: e, 38 capacity: 0, 39 maxCapacity: 2, 40 } 41 } 42 43 func (c *cache) setEvictionAlgo(e evictionAlgo) { 44 c.evictionAlgo = e 45 } 46 47 func (c *cache) add(key, value string) { 48 if c.capacity == c.maxCapacity { 49 c.evict() 50 } 51 c.capacity++ 52 c.storage[key] = value 53 } 54 55 func (c *cache) get(key string) { 56 delete(c.storage, key) 57 } 58 59 func (c *cache) evict() { 60 c.evictionAlgo.evict(c) 61 c.capacity-- 62 } 63 64 func main() { 65 lfu := &lfu{} 66 cache := initCache(lfu) 67 cache.add("a", "1") 68 cache.add("b", "2") 69 cache.add("c", "3") 70 lru := &lru{} 71 cache.setEvictionAlgo(lru) 72 cache.add("d", "4") 73 fifo := &fifo{} 74 cache.setEvictionAlgo(fifo) 75 cache.add("e", "5") 76 }
执行后的输出内容为:
1 Evicting by lfu strategy 2 Evicting by lru strategy 3 Evicting by fifo strategy
 
                    
                 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号