近期在寫 ActivedRouter項目的時候需求一個緩存模型,要求緩存模型支持不同驅動,例如:memory、file、redis、mysql,實現思路代碼如下:
cache.go文件,定義緩存對外接口
//ActivedRouter
//Author:usher.yue
//Amail:[email protected]
//TencentQQ:4223665
//緩存驅動接口定義
//可以自定義擴展驅動類型 默認是 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實現了,具體其他驅動可自行實現
//ActivedRouter
//Author:usher.yue
//Amail:[email protected]
//TencentQQ:4223665
//緩存驅動接口定義
//可以自定義擴展驅動類型 默認是 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
}