Golang中的策略设计模式实例

83 阅读1分钟

Go不是一种面向对象的编程语言,但我们仍然可以在其中复制一些模式。在这个例子中,我们将看到策略设计模式的例子。策略设计模式的行为就像if ... elseswitch ... 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...