Go, nesne yönelimli bir programlama dili değildir, ancak yine de bazı tasarım modellerini kullanabiliriz. Bu örnekte strateji tasarım modeli örneğini göreceğiz. Strateji tasarım modeli if ... else ve switch ... case gibi davranır. Ona bir şey verirsiniz, o da verilenle tam olarak ne yapacağını bilir.


Yapı


internal/
├── cache
│   ├── cache.go
│   ├── file.go
│   ├── redis.go
│   ├── session.go
│   └── strategy.go
└── main.go

Dosyalar


file.go


package cache

import "fmt"

type File struct {}

func (File) push(key, value string, ttl int64) error {
fmt.Println("Pushing [", key, ":", value, "] to file...")

return nil
}

func (File) pop(key string) error {
fmt.Println("Popping [", key, "] from file...")

return nil
}

redis.go


package cache

import "fmt"

type Redis struct {}

func (Redis) push(key, value string, ttl int64) error {
fmt.Println("Pushing [", key, ":", value, "] to redis...")

return nil
}

func (Redis) pop(key string) error {
fmt.Println("Popping [", key, "] from redis...")

return nil
}

session.go


package cache

import "fmt"

type Session struct {}

func (Session) push(key, value string, ttl int64) error {
fmt.Println("Pushing [", key, ":", value, "] to session...")

return nil
}

func (Session) pop(key string) error {
fmt.Println("Popping [", key, "] from session...")

return nil
}

strategy.go


Tüm stratejilerin uyguladığı budur.


package cache

type strategy interface {
push(key, value string, ttl int64) error
pop(key string) error
}

cache.go


Etkileşimde bulunduğumuz kod sadece budur.


package cache

type Cache struct {
Strategy strategy
}

func (c *Cache) Push(key, value string, ttl int64) error {
return c.Strategy.push(key, value, ttl)
}

func (c *Cache) Pop(key string) error {
return c.Strategy.pop(key)
}

main.go


Aşağıda görebileceğiniz gibi, kodu değiştirmeden herhangi bir önbellek mekanizmasını kullanabiliriz. Tek yapmamız gereken bir önbellek stratejisi seçmek. Strateji tasarım modelinin bütün mesele budur.


package main

import (
"log"

"internal/cache"
)

func main() {
var c = &cache.Cache{}

c.Strategy = cache.File{}
if err := c.Push("key-f", "value-f", 3600); err != nil {
log.Fatalln(err)
}

c.Strategy = cache.Redis{}
if err := c.Pop("key-r"); err != nil {
log.Fatalln(err)
}

c.Strategy = cache.Session{}
if err := c.Push("key-s", "value-s", 3600); err != nil {
log.Fatalln(err)
}
}

Test


Pushing [ key-f : value-f ] to file...
Popping [ key-r ] from redis...
Pushing [ key-s : value-s ] to session...