All Articles

Behavioral Design Pattern: Strategy

This article was done using my notes from:

Alexander Shvets (2019), Dive into Design Patterns, Refactoring.Guru

Strategy

Strategy is a behavioral design pattern that turns a set of behaviors into objects and makes them interchangeable inside original context object.

The original object, called context, holds a reference to a strategy object. The context delegates executing the behavior to the linked strategy object.

Structure

Strategy

Code

package main

import "fmt"

type EvictionAlgorithm interface {
	evict(c *Cache)
}

type Cache struct {
	storage          map[string]string
	evictionStrategy EvictionAlgorithm
	capacity         int
	maxCapacity      int
}

func initCache(e EvictionAlgorithm) *Cache {
	storage := make(map[string]string)
	return &Cache{
		storage:          storage,
		evictionStrategy: e,
		capacity:         0,
		maxCapacity:      2,
	}
}

func (c *Cache) setEvictionStrategy(e EvictionAlgorithm) {
	c.evictionStrategy = e
}

func (c *Cache) add(key, value string) {
	if c.capacity == c.maxCapacity {
		c.evict()
	}
	c.capacity++
	c.storage[key] = value
}

func (c *Cache) evict() {
	c.evictionStrategy.evict(c)
	c.capacity--
}

type Fifo struct{}

func (l *Fifo) evict(c *Cache) {
	fmt.Println("Evicting by FIFO strategy")
}

type Lru struct{}

func (l *Lru) evict(c *Cache) {
	fmt.Println("Evicting by LRU strategy")
}

type Lfu struct{}

func (l *Lfu) evict(c *Cache) {
	fmt.Println("Evicting by LFU strategy")
}

func main() {
	lfu := &Lfu{}
	cache := initCache(lfu)

	cache.add("a", "1")
	cache.add("b", "2")

	cache.add("c", "3")

	lru := &Lru{}
	cache.setEvictionStrategy(lru)

	cache.add("d", "4")

	fifo := &Fifo{}
	cache.setEvictionStrategy(fifo)

	cache.add("e", "5")
}