golang 中使用interface实现动态调用
2018年8月5日
程序开发中,我们非常多的时候遇到动态调用的情况,例如我们有多个缓存连接,可能我现在用mc,改天用redis,这个时候,我不能全篇去改变我的代码去实现新的缓存,如果这样那扩展就太不好了!所以我们就要实现用动态的方式去调用,只要简单配置就能改变全局的缓存修改,那天我们添加新的缓存方式,也只要配置一下就可以,工厂模式可以实现这个功能,这里着重讲的是使用golang的interface去实现这个,golang 中interface感觉是神一样的存在,golang源码中大量的使用interface,下边我们简单通过 示例来讲解一下一种可用性,在golang开发中也一定会非常多的应用!
golang中的interface 接口实现是非侵入式的,这样的好处只要struct实现interface的函数,那就说明这个struct实现了这个接口,所以一个接口可以有很多struct实现,一个struct可以实现很多个接口!所以golang是一种非常方便的接口实现!下边用示例来简要说明这种的便利性和方便性,帮助我们可以快速的开发!
下边我们就以cache的例子来说明,首先我们建立一个cache的接口,我们直用cache的读为例子,如果需要写,清除等自行添加:
1 2 3 |
type Cache interface { Read(key string) string } |
这里定义了cache的接口,同时我们需要提供几个cache自动注册的函数,方便各个缓存能自动注册到我们的接口中,方便切换:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
//建立一个适配器,方便注册缓存类型 var adapters = make(map[string]Cache) //注册cache func Register(name string, cache Cache) { if cache == nil { panic("Register Cache is nil") } if _, ok := adapters[name]; ok { panic("Register ~ " + name) } adapters[name] = cache } //使用那个具体的缓存 func NewCache(adapterName string) (cache Cache, err error) { cache, ok := adapters[adapterName] if !ok { err = fmt.Errorf("unknown adapter name %q (forgot to import?)", adapterName) return } return } |
上边弄了一个简单的适配器,方便各个缓存自行注册到缓存适配器中,便于使用 !
下边我们在看下redis和mc的实现和注册:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
func init() { Register("redis", NewRedisCache()) } type RedisCache struct { } func NewRedisCache() Cache{ return &RedisCache{} } func (rc RedisCache) Read(key string) string { //这里读取redis,返回数据 } //下边是mc的实现 func init() { Register("mc", NewMcCache()) } type McCache struct { } func NewMcCache() Cache{ return &McCache{} } func (rc McCache) Read(key string) string { //这里读取mc,返回数据 } |
上边实现了redis和mc的数据读取,从而也实现了cache了接口,这样,我们可以扩展其他的cache缓存,例如file缓存,mysql缓存等等的,非常方便调用!我们看怎么使用
1 2 3 4 5 6 7 |
//我们可以定义全局的缓存选择器,通过修改这个值,我们可以全局一下改变我们使用的缓存 //当然我们也可以用配置文件的方式选择使用的缓存方式 const ( selcache = "redis" ) NewCache(selcache) |
这样我们就随意选择我们的缓存器啦!这里只是以cache的方式来表述一下这种的用法,所以我们可以扩展到很多地方,例如爬虫的时候,我们也可以用这个方式动态的选择不同的爬虫方式或者引擎!