漫谈golang设计模式 工厂模式
工厂模式
意义:创建过程交给专门的工厂子类去完成。定义一个抽象的工厂类,再定义具体的工厂类来生成子类等,它们实现在抽象按钮工厂类中定义的方法。这种抽象化的结果使这种结构可以在不修改具体工厂类的情况下引进新的产品,如果出现新的按钮类型,只需要为这种新类型创建一个具体的工厂类就可以获得该新类型的实例
模式定义
工厂方法模式(Factory Method Pattern)又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建对象的公共接口,而工厂子类则负责生成具体的对象,这样做的目的是将类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体的类。
也就是说要先定义一个抽象工厂作为所有工厂的工厂父类,而为了适配每个类型的实例化,需要为其新建对应的工厂。所以需要用到继承
但是golang没有提供继承机制,只有通过指针传递的方式获取当前父类的实例。也就是匿名函数创建工厂,返回对应的引用
//Operator 是被封装的实际类接口
type Operator interface {
SetA(int)
SetB(int)
Result() int
}
//OperatorFactory 是工厂接口
type OperatorFactory interface {
Create() Operator
}
//OperatorBase 是Operator 接口实现的基类,封装公用方法
type OperatorBase struct {
a, b int
}
//SetA 设置 A
func (o *OperatorBase) SetA(a int) {
o.a = a
}
//SetB 设置 B
func (o *OperatorBase) SetB(b int) {
o.b = b
}
//PlusOperatorFactory 是 PlusOperator 的工厂类
type PlusOperatorFactory struct{}
func (PlusOperatorFactory) Create() Operator {
return &PlusOperator{
OperatorBase: &OperatorBase{},
}
}
//PlusOperator Operator 的实际加法实现
type PlusOperator struct {
*OperatorBase
}
//Result 获取结果
func (o PlusOperator) Result() int {
return o.a + o.b
}
//MinusOperatorFactory 是 MinusOperator 的工厂类
type MinusOperatorFactory struct{}
func (MinusOperatorFactory) Create() Operator {
return &MinusOperator{
OperatorBase: &OperatorBase{},
}
}
//MinusOperator Operator 的实际减法实现
type MinusOperator struct {
*OperatorBase
}
//Result 获取结果
func (o MinusOperator) Result() int {
return o.a - o.b
}
模式分析
工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了面向对象的多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。在工厂方法模式中,核心的工厂类不再负责所有类的创建,而是将具体创建工作交给子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不负责哪一个类被实例化这种细节,这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新的类。
工厂方法模式的优点
工厂方法用来创建客户所需要的类,用户只需要关心所需产品对应的工厂,无须知道具体的类名。
基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够使工厂可以确定创建什么类型的产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,是因为所有的具体工厂类都具有同一抽象父类。
使用工厂方法模式的另一个优点是在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”。
工厂方法模式的缺点
在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。
适用环境
在以下情况下可以使用工厂方法模式:
- 一个类不知道它所需要的对象的类:在工厂方法模式中,客户端不需要知道具体产品类的类名,
只需要知道所对应的工厂即可,具体的产品对象由具体工厂类创建;客户端需要知道创建具体产品的工厂类。 - 一个类通过其子类来指定创建哪个对象:在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,
而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。
将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,
需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中。
模式应用
JDBC中的工厂方法:
Connection conn=DriverManager.getConnection("jdbc:microsoft:sqlserver://loc
alhost:1433; DatabaseName=DB;user=sa;password=");
Statement statement=conn.createStatement();
ResultSet rs=statement.executeQuery("select * from UserInfo");
continue..QwQ
漫谈golang设计模式 工厂模式的更多相关文章
- .NET设计模式: 工厂模式
.NET设计模式: 工厂模式(转) 转自:http://www.cnblogs.com/bit-sand/archive/2008/01/25/1053207.html .NET设计模式(1): ...
- golang 简单工厂模式
package kit //golang简单工厂模式 //go 语言没有构造函数一说,所以一般会定义NewXXX函数来初始化相关类. NewXXX 函数返回接口时就是简单工厂模式,也就是说Golang ...
- 【设计模式】Java设计模式 -工厂模式
[设计模式]Java设计模式 -工厂模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 目 ...
- 漫谈golang设计模式 简易工厂模式
目前学习golang的主要需求是为了看懂TiDB的源码,下面我们复习一下简易工厂模式的思想 工厂类型分为三种,创建型模式,结构型模式,行为型模式. 简单工厂 使用场景:考虑一个简单的API设计,一个模 ...
- [03]Go设计模式:工厂模式(Factory Pattern)
目录 工厂模式 一.简介 二.代码 三.参考资料 工厂模式 一.简介 工厂模式(Factory Pattern)是软件设计中最常用的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象 ...
- [Design Pattern With Go]设计模式-工厂模式
这次介绍的设计模式是工厂模式,这是一个比较常见的创建型模式.一般情况下,工厂模式分为三种:简单工厂.工厂方法和抽象工厂,下面慢慢举例介绍下. 简单工厂 考虑一个加密程序的应用场景,一个加密程序可能提供 ...
- [Head First设计模式]饺子馆(冬至)中的设计模式——工厂模式
系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...
- javascript 设计模式-----工厂模式
所谓的工厂模式,顾名思义就是成批量地生产模式.它的核心作用也是和现实中的工厂一样利用重复的代码最大化地产生效益.在javascript中,它常常用来生产许许多多相同的实例对象,在代码上做到最大的利用. ...
- JavaScript设计模式——工厂模式
工厂模式:是一种实现“工厂”概念的面上对象设计模式.实质是定义一个创建对象的接口,但是让实现这个接口的类来决定实例化哪个类.工厂方法让类的实例化推迟到子类中进行.创建一个对象常常需要复杂的过程,所以不 ...
随机推荐
- .NET Application,Session,Cookie,ViewState,Cache对象用法
作用域 保存地址 生命周期Application 应用程序 服务器内存 IIS启动Session 整个站点 服务器内存 Session到时 默认20分钟Cashe 应用程序 服务器内存 应用程序的周期 ...
- 上手Neo4j
Neo4j是什么 软件安装及常用的配置选项介绍 下载 wget https://neo4j.com/artifact.php?name=neo4j-community-3.5.3-unix.tar.g ...
- css样式优先级计算规则
css样式的优先级分为引入优先级和声明优先级. 引入优先级 引入样式一般分为外部样式,内部样式,内联样式. 外部样式:使用link引入的外部css文件. 内部样式:使用style标签书写的css样式. ...
- C#函数(构造函数)的重载
using System; namespace test { class Program { static void Main(string[] args) { Cat cat = new Cat() ...
- Python中为什么不能用可变对象作为默认参数的值
def func(numbers = [], num=1): numbers.append(num) for number in numbers: print(number) func() >& ...
- maven仓库之第二篇
1. 什么是maven? 它是一个软件开发的管理工具,主要管理的工作是:依赖管理,项目构建. 2. 使用maven的好处? 能够集中管理jar包,提供一键构建. 3. maven的安装及配置 配置:M ...
- JS基础语法---对象总结
* 编程思想: * 面向过程:凡事亲力亲为,所有的事情的过程都要清楚,注重的是过程 * 面向对象:提出需求,找到对象,对象解决这个问题,我们要结果,注重的是结果 * ...
- React Native之React Navigation踩坑
自动重装系统之后,已经很长一段时间没有来写React Native了,今天空闲之余,决定重新配置React Native的开发环境,继续踩坑... React Native的开发环境配置狠简单,只要依 ...
- Azure 架构师认证考试
Azure认证路线 AZ-300 AZ-301 https://blog.csdn.net/pg_edb/article/details/86794505 免费题 https://iteablue.c ...
- 非法指令(Illegal Instruction)问题定位
关键词:Illegal Instruction.SIGILL等. 进程在运行过程中会收到SIGILL信号,此类错误是由操作系统发送给进程的. SIGILL是某个进程中的某一句不能被CPU识别指令,这些 ...