Go不是一种面向对象的编程语言,但我们仍然可以在其中复制一些模式。在这个例子中,我们将看到策略设计模式的例子。策略设计模式的行为就像if ... else 和switch ... case 语句一样,所以你给它一些东西,它就知道到底该怎么做。
结构
internal/
├── cache
│ ├── cache.go
│ ├── file.go
│ ├── redis.go
│ ├── session.go
│ └── strategy.go
└── main.go
文件
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
这是所有策略的实现:
package cache
type strategy interface {
push(key, value string, ttl int64) error
pop(key string) error
}
cache.go
这是我们在代码中互动的部分:
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
正如你所看到的,我们可以在不改变代码的情况下使用任何缓存机制。我们所要做的就是,选择一个缓存策略。这就是策略模式的全部意义所在。
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)
}
}
测试
Pushing [ key-f : value-f ] to file...
Popping [ key-r ] from redis...
Pushing [ key-s : value-s ] to session...