 
                Strategia w języku Go
Strategia to behawioralny wzorzec projektowy zakładający przekształcenie zestawu zachowań w obiekty, które można stosować zamiennie w pierwotnym obiekcie.
Pierwotny obiekt, zwany kontekstem, przechowuje odniesienie do obiektu-strategii i deleguje mu działania związane z danym zachowaniem. Aby zmienić sposób, w jaki kontekst wykonuje swą pracę, należy zamienić bieżąco przypisany obiekt strategii na inny.
Przykład koncepcyjny
Przypuśćmy, że tworzymy schowek w obrębie pamięci. Skoro znajduje się w pamięci, to ma pewien ograniczony rozmiar. Gdy ilość danych w schowku wyczerpie dostępną pamięć, niektóre wpisy muszą zostać z niego usunięte aby zwolnić miejsce. Może się to odbywać według kilku algorytmów, z których najpopularniejsze to:
- Najrzadziej ostatnio używane (LRU): usuwa wpis który był ostatnio najrzadziej potrzebny.
- Pierwszy na wejściu, pierwszy na wyjściu (FIFO): usuwa najwcześniejszy wpis.
- Najrzadziej używane (LFU): usuwa najrzadziej używany wpis.
Problemem jest teraz rozsprzęgnięcie naszej klasy pamięci podręcznej i powyższych algorytmów tak, aby można było wybrać odpowiedni w trakcie działania programu. Ponadto, klasa pamięci podręcznej nie powinna ulegać zmianom gdy dodawany jest nowy algorytm.
Tu właśnie z pomocą przychodzi nam wzorzec Strategia. Proponuje on utworzenie rodziny algorytmów z których każdy z nich będzie osobną klasą. Każda z tych klas będzie zgodna pod względem interfejsu, co pozwoli na wymianę jednego algorytmu na inny. Powiedzmy, że nazwą wspólnego interfejsu jest evictionAlgo.
Od tego momentu nasza główna klasa pamięci podręcznej będzie zawierała interfejs evictionAlgo. Zamiast implementować wszystkie algorytmy zwalniania przestrzeni w klasie, będzie ona delegować te zadania interfejsowi evictionAlgo. Skoro evictionAlgo jest interfejsem, możemy wybrać stosowany algorytm (LRU, FIFO, LFU) w trakcie działania programu bez konieczności zmiany w klasie pamięci podręcznej.
evictionAlgo.go: Interfejs strategii
package main
type EvictionAlgo interface {
	evict(c *Cache)
}
fifo.go: Konkretna strategia
package main
import "fmt"
type Fifo struct {
}
func (l *Fifo) evict(c *Cache) {
	fmt.Println("Evicting by fifo strtegy")
}
lru.go: Konkretna strategia
package main
import "fmt"
type Lru struct {
}
func (l *Lru) evict(c *Cache) {
	fmt.Println("Evicting by lru strtegy")
}
lfu.go: Konkretna strategia
package main
import "fmt"
type Lfu struct {
}
func (l *Lfu) evict(c *Cache) {
	fmt.Println("Evicting by lfu strtegy")
}
cache.go: Kontekst
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: Kod klienta
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.txt: Wynik działania
Evicting by lfu strtegy
Evicting by lru strtegy
Evicting by fifo strtegy