有时候我们在我们自己的项目中需要实现兼容各种驱动的Cache模型,以便于通过配置更换缓存类型。 缓存模型需要支持不同驱动,例如:memory、file、redis、mysql,实现思路代码如下:
cache.go文件,定义缓存对外接口模型代码
//可以自定义扩展驱动类型 默认是 memory driver
package cache
import (
"./driver"
)
//cache接口声明
type Cacher interface {
GetStorage() driver.Containerer
Set(k string, v interface{})
Get(k string) (interface{}, bool)
Del(k string)
Has(k string) bool
}
//create memory cache
//type "file" or "memory"
func Newcache(cacheType string) Cacher {
switch cacheType {
case "memory":
return &driver.CacheImpl{Driver: driver.NewMapContainer()}
case "file":
{
return &driver.CacheImpl{Driver: driver.NewFileContainer()}
}
case "mysql":
{
return &driver.CacheImpl{Driver: driver.NewMysqlContainer()}
}
case "redis":
{
return &driver.CacheImpl{Driver: driver.NewRedisContainer()}
}
case "mongodb":
{
return &driver.CacheImpl{Driver: driver.NewMongoContainer()}
}
}
return nil
}
driver.go 实现驱动,这里我只利用Map实现了,具体其他驱动可自行实现
//可以自定义扩展驱动类型 默认是 memory cache
package driver
//容器接口声明
type Containerer interface {
PushKVPair(k, v interface{}) Containerer
EraseKVPair(k interface{}) Containerer
PushKVMaps(maps ...map[string]interface{}) Containerer
ResetKVPair(k string, v interface{}) Containerer
ResetOrAddKVPair(k string, v interface{}) Containerer
ResetKVPairs(kvMaps map[string]interface{}) Containerer
ResetOrAddKVPairs(kvMaps map[string]interface{}) Containerer
Exist(k interface{}) bool
GetData() *map[string]interface{}
}
//基于内存实现的缓存
type CacheImpl struct {
Driver Containerer //数据缓存驱动
}
func (self *CacheImpl) Exist(k interface{}) bool {
return self.Driver.Exist(k)
}
func (self *CacheImpl) GetStorage() Containerer {
return self.Driver
}
//set
func (self *CacheImpl) Set(k string, v interface{}) {
self.Driver.PushKVPair(k, v)
}
//get
func (self *CacheImpl) Get(k string) (interface{}, bool) {
mapData := *self.Driver.GetData()
val, ok := mapData[k]
return val, ok
}
//erase
func (self *CacheImpl) Del(k string) {
self.Driver.EraseKVPair(k)
}
//has
func (self *CacheImpl) Has(k string) bool {
mapData := *self.Driver.GetData()
_, ok := mapData[k]
return ok
}
//Map实现的内存驱动
type MapContainer struct {
data map[string]interface{}
}
//创建数据channer
func NewMapContainer() *MapContainer {
return &MapContainer{data: make(map[string]interface{})}
}
func (this *MapContainer) PushKVPair(k, v interface{}) Containerer {
if key, ok := k.(string); !ok {
panic("key必须是string类型!")
} else {
this.data[key] = v
}
return this
}
func (this *MapContainer) Exist(k interface{}) bool {
return true
}
func (this *MapContainer) EraseKVPair(k interface{}) Containerer {
if key, ok := k.(string); !ok {
panic("key必须是string类型!")
} else {
delete(this.data, key)
}
return this
}
func (this *MapContainer) PushKVMaps(maps ...map[string]interface{}) Containerer {
for _, itemMap := range maps {
for itemKey, itemValue := range itemMap {
this.PushKVPair(itemKey, itemValue)
}
}
return this
}
func (this *MapContainer) ResetKVPair(k string, v interface{}) Containerer {
if _, ok := this.data[k]; ok {
this.data[k] = v
}
return this
}
func (this *MapContainer) ResetOrAddKVPair(k string, v interface{}) Containerer {
this.data[k] = v
return this
}
func (this *MapContainer) ResetKVPairs(kvMaps map[string]interface{}) Containerer {
for k, v := range kvMaps {
if _, ok := this.data[k]; ok {
this.data[k] = v
}
}
return this
}
func (this *MapContainer) ResetOrAddKVPairs(kvMaps map[string]interface{}) Containerer {
for k, v := range kvMaps {
this.data[k] = v
}
return this
}
func (this *MapContainer) GetData() *map[string]interface{} {
return &this.data
}
到此一个基础Memory类型的驱动就构建完成 ,我们也可以通过这个模型去构建 redis、mysql等等驱动实现自定义缓存。