golang创建式设计模式---工厂模式
创建式设计模式—工厂模式
目录导航
- 创建式设计模式---工厂模式
- 1)什么是工厂模式
- 2)使用场景
- 3)实现方式
- 4)实践案例
- 5)优缺点分析
1)什么是工厂模式
工厂模式(Factory Method Pattern)是一种设计模式,旨在创建对象时,将对象的创建与使用进行分离。通过定义一个工厂类,这个类具有创建不同具体产品对象的方法。用户只需与工厂类交互,告诉工厂自己想要什么类型的产品,工厂就会负责创建并返回相应的产品对象。这样做的好处是使得系统的架构更加清晰、灵活,方便扩展和维护产品的种类,同时也降低了代码之间耦合度。简单来说,就是有个专门负责生产对象的“地方”,根据需求生产出对应的对象。
其uml类图

由图可知,工厂方法模式的角色组成如下
- 工厂(Factory):声明返回的产品对象的工厂方法的接口。该方法返回的对象类型必须与产品接口类型相匹配。
- 具体工厂(ConCreateFactory):实现工厂接口的类,会重写基础工厂方法,使其返回不同类型的产品
- 产品(Product):声明产品方法的接口。对于所有由具体工厂类及其子类构建的对象,该接口是通用的。
- 具体产品(ConcreateProduct):实现产品接口的类
2)使用场景
- 在程序开发过程中,如果开发者无法预知对象的具体类型及其依赖关系,则可以使用工厂方法模式。工厂方法模式将创建产品的工厂代码与产品代码分离,从而降低代码之间的耦合度。例如,如果需要添加一种新产品,则只需创建一个新的具体工厂类,然后重写其工厂方法。
- 如果开发者希望其他开发者可以扩展软件库或框架的内部组件,则可以使用工厂模式。
- 如果一个类需要通过子类指定其创建的对象,则可以使用工厂模式
3)实现方式
package modesimport "fmt"// 定义工厂接口
type Factory interface {//定义一个工厂方法,返回ProductFacMethod(user string) Product
}
// 定义一个具体的工厂类
type ConcreateFactory struct {
}
// 再实现接口的方法
func (cf *ConcreateFactory) FacMethod(user string) Product {p := &ConcreateFactory{} //创建一个具体的工厂实例return p
}
// 定义一个产品接口
type Product interface {Use()
}
//具体的产品类
type ConcreateProduct struct {
}
func (cf *ConcreateFactory) Use() {//TODO implement mefmt.Println("生产一个产品")
}
调用main.go进行测试
package mainimport "factoryMode/modes"func main() {factory := modes.ConcreateFactory{}//生产相关的产品product := factory.FacMethod("fac1")product.Use()
}
4)实践案例
使用工厂模式演示生产两种不同品牌的鞋子(以生产出Nike和aidas为例子吧)
1.定义一个产品接口TShoes,该接口有两个私有方法–setName()和setSize(),以及两个公共方法----GetName()和GetSize()
再定义一个shoes产品类,以及方法用于实现接口的方法,MakeShoes()则是根据shoes品牌的不同生成不同的产品对象并返回:
shoes.go
package exampleimport "fmt"// 定义鞋子产品接口
type TShoes interface {SetName(name string)SetSize(size int)GetName() stringGetSize() int
}// 定义一个shoes类
type shoes struct {name stringsize int
}func (c *shoes) SetName(name string) {c.name = name
}
func (c *shoes) GetName() string {return c.name
}func (c *shoes) SetSize(size int) {c.size = size
}
func (c *shoes) GetSize() int {return c.size
}func MakeShoes(shoesType string) (TShoes, error) {if shoesType == "Nike" {return newNike(), nil}if shoesType == "Adidas" {return newAdidas(), nil}return nil, fmt.Errorf("鞋子类型不对")
}
2.顶一个Nike产品类
package example// 生产Nike鞋子的产品类
type Nike struct {shoes
}func newNike() TShoes {return &Nike{shoes: shoes{name: "Nike shoes",size: 37,},}
}
定义Adidas产品类
package example// 生产Adidas鞋子产品
type Adidas struct {shoes
}func newAdidas() TShoes {return &Adidas{shoes: shoes{name: "Adidas shoes",size: 38,},}
}
3.main.go进行测试
package mainimport ("factoryMode/example""fmt"
)func main() {//创建一个Nike产品对象Nike, _ := example.MakeShoes("Nike")//创建一个Adidas产品对象Adidas, _ := example.MakeShoes("Adidas")PrintInformations(Nike)fmt.Println("----------")PrintInformations(Adidas)} // 此方法用于输出相关鞋子产品的信息,比如名字和尺码
func PrintInformations(s example.TShoes) {fmt.Printf("Shoes:%s", s.GetName())fmt.Println()fmt.Printf("Size:%d", s.GetSize())
}//输出结果为,Shoes:Nike shoes
Size:37----------
Shoes:Adidas shoes
Size:38
5)优缺点分析
优点:
- 应用程序具有可扩展性。在工厂模式中,调用一个方法与新类的实现是完全分离的。这种情况对如何扩展软件有特殊的影响:工厂模式具有高度的自治性,开发者在添加新类后,无须以任何方式更改程序。
- 工厂组件具有单独可测试性。eg:如果工厂模式实现了4个或多个类,则可以单独测试每个类的功能实现
缺点:
-
系统里的类的数量会大幅度成对增加,从而提高该系统的复杂性。工厂模式的实现会导致集成类的数量大量增加,因为每个具体的产品类都需要一个具体的工厂类。尽管工厂模式有利于软件的扩展,但是会增加工作量。如果要扩展工厂模式的产品系列,则必须要调整工厂接口和相应的具体工厂类。因此,针对所需产品类型提前进行可靠规划是非常重要的。
-
工厂组件具有单独可测试性。eg:如果工厂模式实现了4个或多个类,则可以单独测试每个类的功能实现
缺点:
- 系统里的类的数量会大幅度成对增加,从而提高该系统的复杂性。工厂模式的实现会导致集成类的数量大量增加,因为每个具体的产品类都需要一个具体的工厂类。尽管工厂模式有利于软件的扩展,但是会增加工作量。如果要扩展工厂模式的产品系列,则必须要调整工厂接口和相应的具体工厂类。因此,针对所需产品类型提前进行可靠规划是非常重要的。
- 随着抽象层的引入,提高了开发者对系统的理解难度。如果下一个人要接着上一个人的进度,需要阅读和理解抽象层的代码。
相关文章:
golang创建式设计模式---工厂模式
创建式设计模式—工厂模式 目录导航 创建式设计模式---工厂模式1)什么是工厂模式2)使用场景3)实现方式4)实践案例5)优缺点分析 1)什么是工厂模式 工厂模式(Factory Method Pattern)是一种设计模式,旨在创建对象时,将对象的创建与使用进行分离。通过定义…...
高精度定位平板主要应用在哪些领域
高精度定位平板是一种集成了高精度定位技术和强大计算能力的设备,能够提供亚米级甚至厘米级的定位精度。其应用领域广泛,涵盖测绘、精准农业、工程建设、地理信息系统(GIS)、公共安全等多个方面。这种设备凭借其高精度和耐用性&am…...
conda使用常用命令
Conda是一个非常常用的Python包管理器,也是Anaconda Python发行版的一部分。它可以帮助用户安装、更新、卸载Python包,以及管理Python虚拟环境。在这篇博客中,我们将总结一些常用的Conda命令及其用法。 安装和更新Conda 在使用Conda之前&…...
22-LINUX--多线程and多进程TCP连接
一.TCP连接基础知识 1.套接字 所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程…...
像素级创意:深入浅出PixelCNN图像合成技术
参考 https://arxiv.org/pdf/1601.06759 https://blog.csdn.net/zcyzcyjava/article/details/126559327 需要熟悉熵的一些理论、和极大释然估计等价于最小化交叉熵等知识 1. pixelcnn建模方法 pixelcnn做生成模型的想必都有耳闻。它是一种自回归模型,什么是自回归…...
MyBatisPlus使用流程
引入依赖 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.4</version> </dependency> 版本号根据需要选取 在实体类上加注解声明,表信息 根据数…...
爬虫技术升级:如何结合DrissionPage和Auth代理插件实现数据采集
背景/引言 在大数据时代,网络爬虫技术已经成为数据收集的重要手段之一。爬虫技术可以自动化地从互联网上收集数据,节省大量人力和时间成本。然而,当使用需要身份验证的代理服务器时,许多现有的爬虫框架并不直接支持代理认证。这就…...
go 微服务框架kratos错误处理的使用方法及原理探究
通过go语言原生http中响应错误的实现方法,逐步了解和使用微服务框架 kratos 的错误处理方式,以及探究其实现原理。 一、go原生http响应错误信息的处理方法 处理方法: ①定义返回错误信息的结构体 ErrorResponse // 定义http返回错误信息的…...
AI播客下载:Dwarkesh Podcast(关于AI的深度访谈)
Dwarkesh Podcast 是由 Dwarkesh Patel 主持的播客,专注于深度访谈和探讨各种复杂且有趣的话题。该播客在业界获得了极高的评价,被认为是对话和思想交流的平台。 Dwarkesh Podcast 的内容涵盖了多个领域,包括经济学、哲学以及科技等。例如&am…...
C++11function包装器的使用
类模板std::function是一种通用、多态的函数包装。std::function的实例可以对任何可以调用的目标实体进行存储、 复制和调用操作。这些目标实体包括普通函数、Lambda表达式、函数指针、以及其他函数对象等。std::function对象是对 C中现有的可调用实体的一种类型安全的包裹&…...
Vue3判断变量和对象不为null和undefined
Vue3判断变量和对象不为null和undefined 一、判断变量二、判断对象 一、判断变量 在 Vue 3 中,你可以使用 JavaScript 提供的常规方式来检查变量是否不为 null 和不为 undefined。你可以分别使用严格不等运算符 ! 来比较变量是否不为 null 和不为 undefined。以下是…...
C++进阶:C++11(列表初始化、右值引用与移动构造移动赋值、可变参数模版...Args、lambda表达式、function包装器)
C进阶:C11(列表初始化、右值引用与移动构造移动赋值、可变参数模版…Args、lambda表达式、function包装器) 今天接着进行语法方面知识点的讲解 文章目录 1.统一的列表初始化1.1{}初始化1.2 initializer_listpair的补充 2.声明相关关键字2.1a…...
Vue.js Promise 与 async/await 的比较
在现代 Web 开发中,异步操作是不可避免的。在处理异步数据获取时,开发人员通常会使用 Promise 或 async/await。虽然两者都可以实现相同的功能,但它们在代码风格、可读性和错误处理等方面有所不同。本文将对这两种方法进行比较,并…...
Qt 报错总结 No suitable kits found
目录 “No suitable kits found” 解决 解决方法参考: chatGPT辅助解决QT构建报错error: multiple target patterns 我的解决方法:把语言设置为空 “No suitable kits found” 解决 没有找到合适的kits套件,在安装Qt Creator时没有安装Min…...
ThingsBoard如何拆分前后端分离启动
后端启动 前端启动 注意事项 ThingsBoard是一个开源的物联网平台,它原本的设计就考虑到了现代Web应用的前后端分离架构。尽管其核心是一个后端服务,负责设备连接、数据处理和存储等,但其用户界面是作为单独的前端应用程序实现的,…...
加载页面 跳转 新页面 vue
通常,我们点页面上的详情,或者编辑,需要加载一个新的页面出来。 vue中加载页面的方法: 在父页面中(通常是某个模块目录下的index.vue),先写这行代码: import AddEditForm from ./…...
中国主要城市房价指数数据集(2011-2024)
数据来源:东方财富网 时间跨度:2011年1月 - 2024年4月 数据范围:中国主要城市 包含指标: 日期、城市 新建商品住宅价格指数-同比 新建商品住宅价格指数-环比 新建商品住宅价格指数-定基 二手住宅价格指数-环比 二手住宅价格指…...
Creating Server TCP listening socket *:6379: listen: Unknown error
错误: 解决方法: 在redis安装路径中打开cmd命令行窗口,输入 E:\Redis-x64-3.2.100>redis-server ./redis.windows.conf结果:...
JUnit5标记测试用例
使用场景: 通过Tag对用例分组: 环境分组:测试环境、预发布环境阶段分组:冒烟用例版本分组:V1.1、V1.2 Tag标记用例: 设置标签根据标签执行 结合Maven执行结合测试套件执行 设置标签: 通过T…...
在Windows10中重命名文件和文件夹的6种方法,有你熟悉和不熟悉的
序言 你可以通过多种方式在Windows 10上重命名文件。如果每次你想更改文件名时仍右键单击并选择“重命名”,那么我们有一些技巧可以加快更改速度。 使用文件资源管理器重命名文件和文件夹 Windows 10的文件资源管理器是一个功能强大的工具。你知道吗,有四种不同的方法可以…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
pycharm 设置环境出错
pycharm 设置环境出错 pycharm 新建项目,设置虚拟环境,出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...
