LFU<\/strong> – Least Frequently Used: Remove the entry which was least frequently used.<\/li><\/ol>\n\n\n\nNow the problem is how to decouple our Cache class with the algorithm such that we should be able to change the algorithm at run time. Also Cache class should not change when a new algorithm is being added. This is were Strategy Pattern comes into the picture. The strategy pattern suggests creating a family of the algorithm with each algorithm having its own class. Each of these classes follows the same interface and this makes the algorithm interchangeable within the family. Let’s say the common interface name is evictionAlgo<\/strong>.<\/p>\n\n\n\nNow our main Cache <\/strong>class will embed evictionAlgo<\/strong> interface. Instead of implementing all types of eviction algorithms in itself, our Cache class will delegate all it to the evictionAlgo<\/strong> interface. Since evictionAlgo is an interface, we can run time change the algorithm to either be LRU, FIFO, LFU without any change in Cache class.<\/p>\n\n\n\n<\/span>When to Use<\/strong><\/span><\/h2>\n\n\n\nWhen an object needs to support different behavior and you want to change the behavior at run time.<\/li> When you want to avoid a lot of conditionals of choosing the runtime behavior.<\/li> When you have different algorithms that are similar and they only differ in the way they execute some behavior.<\/li><\/ul>\n\n\n\n<\/span>UML Diagram<\/strong><\/span><\/h2>\n\n\n\nNotice below UML diagram, Context (Cache) embeds the strategy (evictionAlgo) interface. <\/p>\n\n\n\n <\/figure><\/li><\/ul><\/figure>\n\n\n\n<\/p>\n\n\n\n
Below is the corresponding mapping UML diagram with the example given above<\/p>\n\n\n\n <\/figure><\/li><\/ul><\/figure>\n\n\n\n<\/span>Mapping<\/strong><\/span><\/h2>\n\n\n\nThe below table represents the mapping from the UML diagram actors to actual implementation actors in code.<\/p>\n\n\n\nContext<\/td> cache.go<\/td><\/tr> Strategy<\/td> evictionAlgo.go<\/td><\/tr> Concrete Strategy Object 1<\/td> lfu.go<\/td><\/tr> Concrete Strategy Object 2<\/td> lru.go<\/td><\/tr> Concrete Strategy Object 3<\/td> fifo.go<\/td><\/tr> Client<\/td> main.go<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<\/span>Practical Example <\/strong><\/span><\/h2>\n\n\n\nevictionAlgo.go<\/strong><\/p>\n\n\n\npackage main\n\ntype evictionAlgo interface {\n evict(c *cache)\n}<\/code><\/pre>\n\n\n\nfifo.go<\/strong><\/p>\n\n\n\npackage main\n\nimport \"fmt\"\n\ntype fifo struct {\n}\n\nfunc (l *fifo) evict(c *cache) {\n fmt.Println(\"Evicting by fifo strtegy\")\n}<\/code><\/pre>\n\n\n\nlru.go<\/strong><\/p>\n\n\n\npackage main\n\nimport \"fmt\"\n\ntype lru struct {\n}\n\nfunc (l *lru) evict(c *cache) {\n fmt.Println(\"Evicting by lru strtegy\")\n}<\/code><\/pre>\n\n\n\nlfu.go<\/strong><\/p>\n\n\n\npackage main\n\nimport \"fmt\"\n\ntype lfu struct {\n}\n\nfunc (l *lfu) evict(c *cache) {\n fmt.Println(\"Evicting by lfu strtegy\")\n}<\/code><\/pre>\n\n\n\ncache.go<\/strong><\/p>\n\n\n\npackage main\n\ntype cache struct {\n storage map[string]string\n evictionAlgo evictionAlgo\n capacity int\n maxCapacity int\n}\n\nfunc initCache(e evictionAlgo) *cache {\n storage := make(map[string]string)\n return &cache{\n storage: storage,\n evictionAlgo: e,\n capacity: 0,\n maxCapacity: 2,\n }\n}\n\nfunc (c *cache) setEvictionAlgo(e evictionAlgo) {\n c.evictionAlgo = e\n}\n\nfunc (c *cache) add(key, value string) {\n if c.capacity == c.maxCapacity {\n c.evict()\n }\n c.capacity++\n c.storage[key] = value\n}\n\nfunc (c *cache) get(key string) {\n delete(c.storage, key)\n}\n\nfunc (c *cache) evict() {\n c.evictionAlgo.evict(c)\n c.capacity--\n}<\/code><\/pre>\n\n\n\nmain.go<\/strong><\/p>\n\n\n\npackage main\n\nfunc main() {\n lfu := &lfu{}\n cache := initCache(lfu)\n cache.add(\"a\", \"1\")\n cache.add(\"b\", \"2\")\n cache.add(\"c\", \"3\")\n lru := &lru{}\n cache.setEvictionAlgo(lru)\n cache.add(\"d\", \"4\")\n fifo := &fifo{}\n cache.setEvictionAlgo(fifo)\n cache.add(\"e\", \"5\")\n}<\/code><\/pre>\n\n\n\nOutput:<\/strong><\/p>\n\n\n\nEvicting by lfu strtegy\nEvicting by lru strtegy\nEvicting by fifo strtegy<\/code><\/pre>\n\n\n\n<\/p>\n\n\n\n
<\/p>\n","protected":false},"excerpt":{"rendered":"
Note: Interested in understanding how all other design patterns can be implemented in GO. Please see this full reference – All Design Patterns in Go (Golang) Table of Contents Definition: When to…<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false},"categories":[1],"tags":[25,3,4,60,61],"class_list":["post-562","post","type-post","status-publish","format-standard","hentry","category-tech","tag-design-pattern","tag-go","tag-golang","tag-strategy-design-pattern","tag-strategy-design-pattern-in-golang"],"yoast_head":"\n
Strategy Design Pattern in Go (Golang) - Welcome To Golang By Example<\/title>\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\t \n\t \n\t \n