设计模式可以大大提高代码复用性,使得程序的修改更加灵活。另外将各个功能模块抽象解耦出来,在某个模块需要更改时不至于会对整体代码进行修改,解耦的好的话只简单修改几个地方即可以切换某个模块在实现上的切换,这就提高了程序修改的灵活度,以便应对客户各种各样的需求。

大话设计模式第一章就通过写一个计算器(计算逻辑和前端显示解耦)和曹操饮酒改诗(每修改或者增加一个字就需要全部重新刻录,并且就的刻版只能作废)例子说明了设计模式的重要性。同时展示了简单工厂模式,简单工厂模式整体的思路是在一个创建函数中,通过switch case语句分别创建不同的实例,但是这些实例都有一些共同的属性,比如加减运算中,在创建一个加法类时,这个类有两个数字和一个返回结果的函数,减法也差不多一样只是返回函数不一样而已。这样我们就可以用简单工厂方法来生成加法类、减法类、乘法类等等。GO的实例代码如下:

//这个interface用来保存大致一样的类
type API interface {Say(name string) string
}//这个是工厂函数,返回一个interface
func NewAPI(t int) API  {if t == 1 {return &hiAPI{}} else if t == 2 {return &helloAPI{}}return nil
}//这个是一个具体的类型,hi
type hiAPI struct{}
func (*hiAPI)Say(name string) string {return fmt.Sprintf("Hi, %s", name)
}
//这是一个具体的类型,hai
type helloAPI struct {
}
func (*helloAPI)Say(name string) string  {return fmt.Sprintf("Hello, %s", name)
}客户端代码:
func TestType1(t *testing.T)  {api := NewAPI(1)s := api.Say("Tom")if s != "Hi, Tom" {t.Fatal("Type1 test failed")}
}

简单工厂模式在增加一个新的类型时,除了要增加新的类和方法之外,还需要修改工厂函数,在工厂函数中添加case,这一点违背了对修改关闭这个原则(开放-封闭原则),所以需要工厂模式。

工厂模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。看一下代码你就知道了

package factoryCreatetype Operator interface {SetA(int)SetB(int)Result() int
}//定义一个用于创建对象的接口
//实际中是这个interface在各个函数中传来传去,当需要实例化一个类的时候,调用Create方法
//具体的加减函数中,使用这个interface的Create方法返回的Operator interface做各种加减
type OperatorFactory interface {Create() Operator
}type OperatorBase struct {a, b int
}
//set A
func (o *OperatorBase) SetA(a int) {o.a = a
}
//SetB
func (o *OperatorBase) SetB(b int) {o.b = b
}//这里还创建一个新的加法工厂类,这个依赖于下面的具体加法类
type PlusOperatorFactory struct {
}
//这个类实现了这个方法之后,不但可以让这个类的实例赋值给OperatorFactory
//还可以通过这个函数创建加法实际操作的实例-PlusOperator类型的实例
func (PlusOperatorFactory) Create() Operator {return &PlusOperator{OperatorBase: &OperatorBase{},}
}
//具体的加法类
type PlusOperator struct {*OperatorBase
}
func (o PlusOperator) Result() int {return o.a + o.b
}//减法工厂类,依赖于下面的具体减法类
type MinusOperatorFactory struct{}
func (MinusOperatorFactory) Create() Operator {return &MinusOperator{OperatorBase: &OperatorBase{},}
}
//具体的减法类
type MinusOperator struct {*OperatorBase
}
func (o MinusOperator) Result() int {return o.a - o.b
}//**************************客户端代码:
func compute(factory OperatorFactory, a, b int) int {op := factory.Create()op.SetA(a) //这里类似于虚函数调用实际的子类函数。。。op.SetB(b)return op.Result()
}func TestOperator(t *testing.T) {var (factory OperatorFactory //类似于基类)factory = PlusOperatorFactory{} //类似于一个子类if compute(factory, 1, 2) != 3 {t.Error("error with factory method pattern")}factory = MinusOperatorFactory{} //另一个子类if compute(factory, 4, 2) != 2 {t.Fatal("error with factory method pattern")}
}

工厂函数在增加一个新的类型的时候,像上面的例子里,只要增加一个新类型的工厂类,里面实现

Create() Operator方法,同时增加具体类型type MinusOperator struct {  *OperatorBase} 就好了。这里的OperatorBase是一个技巧。没有违背开放-封闭原则。我们注意在客户端中computer函数中我们可以做到不管你是加法还是减法,我们都调用了名字“一样”的函数,运算与类的产生已经有所解耦了。但是假如,上面的例子中,我们不仅仅要产生Operator方法,我们还要给第一个数上黄色,第二个数上绿色,如果我们在Operator中添加方法的话,显然需要改动的地方就太多了,我们应该是添加一个新的interface,里面有setAColor(),setBColor()方法,在客户端我们拿到这个新的interface,然后调用setAColor()比较可取。这个功能就需要用到抽象工厂模式了

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

package abstractfactoryimport "fmt"type OrderMainDAO interface {SaveOrderMain()
}type OrderDetailDAO interface {SaveOrderDetail()
}
//这是一个接口,这个接口会创建一系列相互依赖(RDBDAOFactory和XMLDAOFactory 依赖于 OrderMainDAO)、
// 或者相互相关(OrderMainDAO和OrderDetailDAO相关)的对象,
//在客户端中创建RDBDAOFactory和XMLDAOFactory时,并不需要指定这两个类型
type DAOFactory interface {CreateOrderMainDAO() OrderMainDAOCreateOrderDetailDAO() OrderDetailDAO
}type RDBMainDAO struct {
}
func (*RDBMainDAO) SaveOrderMain() {fmt.Print("rdb main save\n")
}type RDBDetailDAO struct {
}
func (*RDBDetailDAO) SaveOrderDetail() {fmt.Sprint("rdb detail save\n")
}type RDBDAOFactory struct {
}
func (*RDBDAOFactory) CreateOrderMainDAO() OrderMainDAO {return &RDBMainDAO{}
}
func (*RDBDAOFactory) CreateOrderDetailDAO() OrderDetailDAO {return &RDBDetailDAO{}
}//**********************type XMLMainDAO struct {
}
func (*XMLMainDAO) SaveOrderMain() {fmt.Sprint("xml main save\n")
}type XMLDetailDAO struct {
}
func (*XMLDetailDAO) SaveOrderDetail() {fmt.Print("xml datail save")
}type XMLDAOFactory struct {
}
func (*XMLDAOFactory) CreateOrderMainDAO() OrderMainDAO {return &XMLMainDAO{}
}
func (*XMLDAOFactory) CreateOrderDetailDAO() OrderDetailDAO {return &XMLDetailDAO{}
}

客户端代码

func getMainAndDetail(factory DAOFactory) {factory.CreateOrderMainDAO().SaveOrderMain()factory.CreateOrderDetailDAO().SaveOrderDetail()
}func TestRdbFactory(t *testing.T) {var factory DAOFactoryfactory = &RDBDAOFactory{}getMainAndDetail(factory)
}func TestXmlFactory(t *testing.T) {var facotry DAOFactoryfacotry = &XMLDAOFactory{}getMainAndDetail(facotry)
}

这里如果我们要在添加新的操作,也就是在DAOFactory这个interface中添加新的操作,我们需要改的地方就比较多。我们可以用简单工厂来封装一下,然后在简单工厂函数中用反射来自动判断需要创建那种类型,这是比较高级的玩法,留作练习。

GOLANG工厂模式、简单工厂模式、抽象工厂模式、创建者模式相关推荐

  1. Java设计模式-工厂模式(3)抽象工厂模式

    在Java设计模式-工厂模式(2)工厂方法模式 我们知道了工厂方法模式解决了简单工厂模式中的缺陷,做到了满足开闭原则,但是时代是进步的,进而又产生新的问题,工厂难道只能生产一种东西吗.我们所见到的工厂 ...

  2. 抽象工厂模式_设计模式(3) 抽象工厂模式

    抽象工厂模式 优化抽象工厂 异步工厂 在学习抽象工厂模式前,先来回顾一下前面的简单工厂和工厂方法模式.简单工厂的职责非常简单:构造某个实体类型,然后把实例作为抽象类型返回: 工厂方法模式则进一步抽象出 ...

  3. 工厂模式三部曲之三_抽象工厂模式(附三部曲源码)

    抽象工厂模式是对工厂模式的进一步抽象,是工厂模式中最为抽象和最具一般性的一种形态,提供了创建一系列相关或者相互依赖对象的接口,而无需指定他们的类型. 如果你对工厂模式还有些迷惑的,可以回顾下工厂模式的 ...

  4. 【设计模式】11-15:迪米特拉(最小知识)原则、外观模式、建造者模式、观察者模式、抽象工厂模式...

    十一.迪米特拉原则/最小知识原则 如果两个类直接进行通信,那么这两个类就不能存在关系 调用其他类的方法时,需要第三个类实现转发-->外观类 尽量降低类的访问权限 十二.外观模式 隐藏系统的复杂性 ...

  5. 设计模式总结四(外观模式、建造者模式、观察者模式和抽象工厂模式)

    序 这么多天里,我已经读完了<大话设计模式>.放寒假了,没有了通过学业考试的重担,阅读技术书籍的时间页多出来了不少. 在今天我刚阅读了<kafka权威指南>的第一章,关于介绍k ...

  6. 抽象工厂模式_常用设计模式--抽象工厂模式

    抽象工厂模式 定义 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 作用 在工厂方法模式中,我们的具体创建者每次使用都只能创建一个同类型的对象,假如我们现在需要的是多个不同类型的 ...

  7. FactoryMethod工厂方法模式升级成AbstractFactory抽象工厂模式

    具体参考抽象工厂(AbstractFactory)模式-创建型模式,本文在FactoryMethod工厂方法模式(创建型模式)的基础上进行业务进一步抽象,不做详细原理介绍. 1.在FactoryMet ...

  8. 抽象工厂模式_设计模式系列—抽象工厂模式

    前言 23种设计模式速记 单例(singleton)模式 工厂方法(factory method)模式 23种设计模式快速记忆的请看上面第一篇,前面说完了工厂方法模式,我们发现工厂方法模式存在一个严重 ...

  9. python抽象工厂模式_Python设计模式之抽象工厂模式

    Python设计模式之抽象工厂模式 这篇文章主要为大家详细介绍了Python设计模式之抽象工厂模式,感兴趣的小伙伴们可以参考一下 python面向对象编程入门,我们需要不断学习进步 "&qu ...

  10. 设计模式【2.2】-- 工厂模式怎么演变成抽象工厂模式?

    还记得之前的工厂方法模式么?现在老板更加富有了,除了水果,还准备搞点其他的生意,再做点服装生意.水果工厂和服装工厂明显就不是同一种东西,肯定不能放到一个工厂里面生产,服装也有好几种,但是不同的工厂,也 ...

最新文章

  1. ORACLE分页SQL
  2. 算法应用 ---拆分字符串为n节字符
  3. jquery对输入框内容的数字校验
  4. 网页空间php可以赋值,js如何赋值给php
  5. 【 ➰斗艳争妍の网络协议姐妹花‍‍️➰】http协议 VS websocket协议
  6. c#中namespace、assembly与DLL/EXE
  7. RxSwift之深入解析核心逻辑Observable的底层原理
  8. 微软出手,蚕食JetBrains系市场?
  9. 【英语学习】【Daily English】U09 Fashion L04 It helps if you look the part
  10. CCIE考试现在需要面试了
  11. 潜谈IT从业人员在传统IT和互联网之间的择业问题(上)-传统乙方形公司
  12. 字节跳动社招面试记录,java异常处理关键字
  13. Oracle笔记(一) Oracle简介及安装
  14. 使用jqery模拟网易严选购物车功能
  15. Python CSV模块
  16. 看共享单车上的智能车锁有何区别
  17. Java通过代理服务器上网
  18. Nodejs异步回调的优雅处理方法
  19. H5的rem适配方案
  20. 4. 软件工程:航空行李托运费计算

热门文章

  1. 第六节课 pycharm
  2. cuda 和 pytorch 安装
  3. fx5u模拟量如何读取_三菱FX5U PLC内置模拟量输入为电流怎么设置?
  4. java防止重复提交
  5. (PTA)数据结构(作业)11、树和图
  6. 2021-2027全球与中国网眼织物纺织品市场现状及未来发展趋势
  7. 期末题库是Excel版的,如何转化成Word版
  8. 狗年已到,今天送3万元红包,本文有4个答案
  9. 神箭手 爬虫操作(1)
  10. 教你如何关闭Win7视频预览节约资源