go设计模式之工厂模式浅谈

go_hiro · · 935 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

## 工厂模式 #### 1.简单工厂 ```go //定义两个生成动物的工厂,一个生成Dog,一个生成Cat type Cat struct{} type Dog struct{} //定义一个接口,为了代码简单,这里我定义了一个空接口,这样Dog,Cat就不用实现任何方法 type Animal interface{} //简单工厂方法,用于生成具体动物 func Create(animalType string) Animal { var animal Animal switch animalType { case "cat": animal = &Cat{} case "dog": animal = &Dog{} } return animal } ``` 以上就是一个简单工厂模式 使用如下: ```go cat := Create("cat") dog := Create("dog") ``` 一切看上去好像很完美,但是当我们需要新加入一种动物(即新添加一个工厂)时,我们还是需要修改两处地方,修改如下 ```go //第一处修改,新建一个动物结构(如duck) type Duck struct{} //第二处修改 func Create(animalType string) Animal { var animal Animal switch animalType { case "cat": animal = &Cat{} case "dog": animal = &Dog{} case "duck": //++++此处为新增逻辑 animal = &Duck{} } return animal } ``` 修改Create方法并不是明智之举,很明显违背了设计模式的开闭原则,那有什么方法加以改善??? 由于本人也是刚接触go,在这里提出以下想法,写得不好,或者有什么问题,希望各位看官指正,经过修改代码如下 #### 2.工厂方法 ```go //定义两个生成动物的工厂,一个生成Dog,一个生成Cat type Cat struct{} type Dog struct{} //定义一个接口 type Animal interface{} //Cat的构造函数 func CreateCat() Animal{ retrun &Cat{} } //Dog的构造函数 func CreateDog() Animal{ retrun &Dog{} } ``` ```go //定义一个工厂结构 //结构里面只有一个类型为[string]func() Animal的map,它主要是用来存放各种动物的”构造函数“ type Factry struct { animals map[string]func() Animal } ``` 为了描述方便我们可以把func() Animal定义为CreateFn ```go type CreateFn func() Animal //于是Factry可以改写为 type Factry struct{ animals map[string]CreateFn } ``` 定义一个newFactry方法,方法主要用于生成Factry实列,并且构建animals,目的是为了构建一个描述动物关键字(如:”cat"代表Cate,"dog"代表Dog)与各动物”构造函数“的映射 ```go func newFactry() *Factry { return &Factry{ animals: map[string]CreateFn{ "dog": CreateDog,//把"dog"关键字映射到构造函数CreateDog "cat": CreateCat, }, } } ``` 至此主要逻辑就已经完成了,剩下怎么创建具体动物这一步了,我们给Factry结构体添加一个Create方法方法,如下: ```go func (f *Factry) Create(name string) Animal { //name为关键字,通过关键字,我们可以从animals找到对应的构造函数 return f.animals[name]() } ``` ### 大功告成 至此工厂方法已经好了,那怎么使用列?如下: ```go fac := newFactry() //新建一个工厂 dog := fac.Create("dog")//新建一个dog cat := fac.Create("cat") //新建一个cat ``` ## 总结:通过以上改造,我们解决了简单工厂添加新工厂存在的问题,即需要添加新分支: ```go case "duck": //++++此处为新增逻辑 animal = &Duck{} ``` ### 因为,我们统一把分支管理交给了工厂结构体里的animals map[string]CreateFn来管理,这样添加新动物时,我们只需要专心写我们的动物结构就可以了,写好后在animals 添加对应关系即可, ### 通过这样的改造,我们虽然解决了修改case分支的问题,但又多了新问题,需要维护animals ,看上去好像也没有什么改善,但对于大型复杂的软件工程来说,维护animals,应该比维护case分支好,通过维护animals,我们把创建具体动物的权限交还给了动物的“构造函数”本身,使得动物结构更加合理,而不是把构建交给case 以上就是我的愚见,希望大家参考改进,有什么好的想法,请大家留意,共同进步!!!

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

935 次点击  
加入收藏 微博
4 回复  |  直到 2021-04-25 17:47:35
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传