【设计模式】创建型模式——简单工厂模式

news2024/11/13 11:03:26

文章目录

  • 一、创建型模式
    • 1. 包含模式
      • 1.1 工厂模式
      • 1.2 建造者模式
      • 1.3 原型模式
      • 1.4 单例模式
  • 二、工厂模式
    • 1. 概要
      • 1.1 意图
      • 1.2 主要解决问题
      • 1.3 何时使用
      • 1.4 如何解决
      • 1.5 关键代码
      • 1.6 使用场景
      • 1.7 优点
      • 1.8 缺点
      • 1.9 简单工厂实现
    • 2. 简单工厂模式
      • 2.1 模式结构
      • 2.2 实例
      • 2.3 模式定义
      • 2.4 模式分析
      • 2.5 适用情况
      • 2.6 特点
        • 2.6.1 优点
        • 2.6.2 缺点


一、创建型模式

创建型模式对类的实例化过程进行了抽象,能够将软件模块中对象的创建和对象的使用分离。

为了使软件的结构更加清晰,外界对于这些对象只需要知道它们共同的结构,而不清楚其具体的实现细节,使整个系统的设计更加符合单一职责原则。

创建型模型在创建什么(What),由谁创建(Who),何时创建(When)等方面都为软件设计者提供了尽可能大的灵活性。

创建型模式隐藏了类的实例的创建细节,通过隐藏对象如何被创建和组合在一起达到使整个系统独立的目的。

1. 包含模式

1.1 工厂模式

  1. 简单工厂模式
  2. 工厂方法模式
  3. 抽象工厂模式

1.2 建造者模式

1.3 原型模式

1.4 单例模式

二、工厂模式

工厂模式是最常用的设计模式之一,提供了一种创建对象的方式,使得对象的创建过程与对象的使用过程分离。
工厂模式提供了一种创建对象的方式,而无需指定要创建的具体类。
通过使用工厂模式,可以将对象的创建逻辑封装在一个工厂类中,而不是在客户端代码中直接实例化对象,这样可以提高代码的可维护性和可扩展性。

1. 概要

概要内容偏书面化,读起来有点绕,看看代码实现就很容易理解啦~~我个人体验概要不需要读,直接看代码也能明白做法的意图啦

1.1 意图

定义一个创建对象的接口,让其子类决定实例化哪一个具体的类。工厂模式使对象的创建过程延迟到子类。

1.2 主要解决问题

接口选择的问题。

1.3 何时使用

当需要在不同条件下创建不同实例时。

1.4 如何解决

通过让子类实现工厂接口,返回一个抽象的产品。

1.5 关键代码

对象的创建过程在子类中实现。

1.6 使用场景

  1. 日志记录:日志可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志的位置。
  2. 数据库访问:当用户不知道最终系统使用哪种数据库,或者数据库可能变化时。
  3. 连接服务器的框架设计:需要支持 “POP3”、“IMAP”、“HTTP” 三种协议,可以将这三种协议作为产品类,共同实现一个接口。

1.7 优点

  1. 调用者只需要知道对象的名称即可创建对象。
  2. 扩展性高,如果需要增加新产品,只需扩展一个工厂类即可。
  3. 屏蔽了产品的具体实现,调用者只关心产品的接口。

1.8 缺点

每次增加一个产品时,都需要增加一个具体类和对应的工厂,使系统中类的数量成倍增加,增加了系统的复杂度和具体类的依赖。

1.9 简单工厂实现

创建一个 Shape 接口和实现 Shape 接口的实体类。下一步是定义工厂类 ShapeFactory。

FactoryPatternDemo 类使用 ShapeFactory 来获取 Shape 对象。它将向 ShapeFactory 传递信息(CIRCLE / RECTANGLE / SQUARE),以便获取它所需对象的类型。
在这里插入图片描述

package main

import "fmt"

// Shape 接口
type Shape interface {
	Draw()
}

// Rectangle 结构体
type Rectangle struct{}

// Draw 方法实现
func (r *Rectangle) Draw() {
	fmt.Println("Inside Rectangle::draw() method.")
}

// Square 结构体
type Square struct{}

// Draw 方法实现
func (s *Square) Draw() {
	fmt.Println("Inside Square::draw() method.")
}

// Circle 结构体
type Circle struct{}

// Draw 方法实现
func (c *Circle) Draw() {
	fmt.Println("Inside Circle::draw() method.")
}

// ShapeFactory 结构体
type ShapeFactory struct{}

// GetShape 方法
func (f *ShapeFactory) GetShape(shapeType string) Shape {
	switch shapeType {
	case "CIRCLE":
		return &Circle{}
	case "RECTANGLE":
		return &Rectangle{}
	case "SQUARE":
		return &Square{}
	default:
		return nil
	}
}

// 主函数
func main() {
	shapeFactory := &ShapeFactory{}

	// 获取 Circle 的对象,并调用它的 Draw 方法
	shape1 := shapeFactory.GetShape("CIRCLE")
	shape1.Draw()

	// 获取 Rectangle 的对象,并调用它的 Draw 方法
	shape2 := shapeFactory.GetShape("RECTANGLE")
	shape2.Draw()

	// 获取 Square 的对象,并调用它的 Draw 方法
	shape3 := shapeFactory.GetShape("SQUARE")
	shape3.Draw()
}

2. 简单工厂模式

2.1 模式结构

简单工厂模式包含如下角色:

1. Factory:工厂角色
工厂角色负责实现创建所有实例的内部逻辑。

2. Product:抽象产品角色
抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口。

3. ConcreteProduct:具体产品角色
具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。
在这里插入图片描述

2.2 实例

工厂类负责创建对象,客户端只需调用工厂方法。

package main

import "fmt"

// Shape 接口
type Shape interface {
	Draw()
}

// Circle 结构体
type Circle struct{}

func (c *Circle) Draw() {
	fmt.Println("Drawing a Circle")
}

// Rectangle 结构体
type Rectangle struct{}

func (r *Rectangle) Draw() {
	fmt.Println("Drawing a Rectangle")
}

// ShapeFactory 简单工厂
type ShapeFactory struct{}

func (f *ShapeFactory) GetShape(shapeType string) Shape {
	switch shapeType {
	case "CIRCLE":
		return &Circle{}
	case "RECTANGLE":
		return &Rectangle{}
	default:
		return nil
	}
}

// 主函数
func main() {
	factory := &ShapeFactory{}

	shape1 := factory.GetShape("CIRCLE")
	shape1.Draw()

	shape2 := factory.GetShape("RECTANGLE")
	shape2.Draw()
}

2.3 模式定义

简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。
在简单工厂模式中,可以根据参数的不同返回不同类的实例。
简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

2.4 模式分析

  • 将对象的创建和对象本身业务处理分离可以降低系统的耦合度,使得两者修改起来都相对容易。
  • 在调用工厂类的工厂方法时,由于工厂方法是静态方法,使用起来很方便,可通过类名直接调用,而且只需要传入一个简单的参数即可,在实际开发中,还可以在调用时将所传入的参数保存在XML等格式的配置文件中,修改参数时无须修改任何源代码。
  • 简单工厂模式最大的问题在于工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,这一点与开闭原则是相违背的。
  • 简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。

2.5 适用情况

  • 工厂类负责创建的对象比较少:由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
  • 客户端只知道传入工厂类的参数,对于如何创建对象不关心:客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。

2.6 特点

2.6.1 优点
  • 工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品;简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象。
  • 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
  • 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
2.6.2 缺点
  • 由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
  • 使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
  • 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
  • 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2092831.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Charles激活

简介 Charles激活码计算 激活 Help -> Register Charles 添加 Registered Name 和计算出的 License key 点击 Register Java import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Random; import java.util.Scanner;/*** program: ZK* descriptio…

开关二极管损坏如何判断

系列文章目录 1.元件基础 2.电路设计 3.PCB设计 4.元件焊接 5.板子调试 6.程序设计 7.算法学习 8.编写exe 9.检测标准 10.项目举例 11.职业规划 文章目录 前言1. 外观检查2. 测量正向压降3. 反向电阻测量4. 电路功能测试5. 高压测试6. 加热测试 前言 送给大学毕业后找不到奋…

【Java】 为什么是split 方法按点号分割是用 “ \\. “ ?

前言: 小知识,记录自用and分享。 原因分析: 字符串的很多方法是可以使用正则表达式的,这里就包括了split这个方法。 . 在正则表达式里的意思是通配符,表示:匹配任意单个字符。那么,当使用split…

参加 帆软 BI 上海城市 课堂(08-30培训)

参加 帆软 BI 城市 课堂(0830): 由于目前是自由职业,也想学习一下新的知识 。所以参加本次的培训,总的来说还是比较专业。 培训在 上海 帆软的总部 环球港进行。时间是 13:30~17:00 老师很专业。学习中 课…

家具大卖nouhaus独立站拆解丨出海笔记

今天我们分析下一家传统外贸起家的大卖独立站:www.nouhaus.com 品牌背景是恒林股份(A股603661)旗下,算是有上市公司支持了。据资料显示:恒林股份成立于1998年,一年能卖出1000万件的办公椅和沙发&#xff0…

合并多个rtf文件

合并多个rtf文件,有2个细节: 1、不同文件之间加分页 2、编号的处理 选择一个目录 private void BtnImportingDirectoryBrowse_Click(object sender, EventArgs e){if (FbdlgDirectory.ShowDialog() DialogResult.OK){textBox1.Text FbdlgDirectory.S…

Linux---文件(1)---初识文件

目录 预备知识 文件操作接口 打开文件接口 重定向与文件操作关系 "w"方式与重定向 “a”方式与追加重定向 写入文件接口 读取文件接口 系统调用接口 参数解析 预备知识 我们知道,创建出一个空文件也要在内存中占空间。 文件文件内容文件属性 操…

raw.githubusercontent.com未能解析” 解决方案

1.操作场景 通过windows11 powershell 下载依赖包 2.报错信息如下 irm : 未能解析此远程名称: raw.githubusercontent.com 所在位置 行:1 字符: 27 & ([scriptblock]::Create((irm "https://win11debloat.raphi.re/"))) ~~~~~~~~~…

C++知识点总结(54):复杂模拟综合

复杂模拟综合 例题1. 玩具谜题2. 猴子兄弟爬山3. 浇水4. 数组旋转5. 石头剪刀布6. 巨石滚滚 例题 1. 玩具谜题 小南有一套可爱的玩具小人,它们各有不同的职业。 有一天,这些玩具小人把小南的眼镜藏了起来。 小南发现玩具小人们围成了一个圈&#xff0c…

llm 是泡沫?

这篇文章不谈技术,只想聊聊自己这两年从事 llm 工作的一些感悟。 我个人对 llm 是一种很复杂的态度。毕竟,它真的击碎了我 2023 年之前所有的技术积累,以前在 nlp 苦心钻研的训练经验、模型结构、不同任务类型的不同处理技巧,好像…

个微管理撤回删除的消息都可以查看

有没有经历过误删微信消息的尴尬时刻?😅或者想知道撤回的消息到底是什么内容?今天,我要向大家推荐一个多功能微管理神器,帮你轻松解决这些问题!💪💌 1️⃣ 多个账号同时在线 &#x…

nefu暑假集训3 并查集与最小生成树 个人模板+例题汇总

前言&#xff1a; 并查集与最小生成树的训练。 正文&#xff1a; 链接&#xff1a;并查集与最小生成树 - Virtual Judge (vjudge.net) 题目&#xff1a; A - 关押罪犯&#xff1a; #include <bits/stdc.h> using namespace std; const int N200005; int fa[N],d[N]; …

实现一个能设置MaxLine的LayoutManager

实现一个能设置MaxLine的LayoutManager 有时候&#xff0c;我们会遇到这种需求&#xff1a;一个线性的列表布局&#xff0c;当item量很少的时候&#xff0c;就是wrap_content直接展示完所有item&#xff0c;但是当item数量超过某个数时就要固定高度&#xff0c;让其变成可滑动…

AOP 面向切片编程

目录 1. 什么是AOP 2. AOP的应用场景 3. AOP在Java中的实现 4. Spring AOP概述 5. Spring AOP的配置 1.在pom.xml文件中添加Spring AOP的依赖&#xff1a; 2. 定义切面 3. 启用AOP 4. 目标类 5. 测试AOP 6. AOP与其他技术的对比 面向切面编程&#xff08;AOP, Aspec…

SPI通信(软件模拟)

1 软件SPI程序框架 2 软件SPI交换一个字节的先后顺序 3 读取W25q64芯片厂商ID,设备ID 4 宏定义W26q64指令码 5 页缓冲区最大256字节&#xff0c;超过就会忙碌 6 页编程

生产环境中变态开启devtools(强制)

写到最前面 首先&#xff0c;你已经下载了google的插件【vue devtools】&#xff0c;不知道怎么下载&#xff0c;留言博主 如果你想看的项目中的vuetools插件打开是这样的 Vue.js is detected on this page. Devtools inspection is not available because it’s in product…

【中学教资-信息技术】多媒体文件大小的存储

图像/音频/视频文件大小的计算 1 图像文件2 音频文件3 视频文件4 例题5 总结 视频讲解&#xff1a;音频文件大小/视频文件大小计算-失舵之舟 1 图像文件 压缩比原始大小/被压缩之后大小 颜色深度&#xff1a;指图像中每个像素所占的二进制位数&#xff08;bit&#xff09; n位…

BioXM一款实用的生物小软件

软件介绍 BioXM是一款非常简单明了的分子生物学软件&#xff0c;全中文操作界面非常友好。 DNA序列分析、蛋白质序列分析、多序列比对、氨基酸相似性计算、酶切位点分析、ORF分析、分子量和等电点预测、序列数据库等。 软件下载 https://pan.quark.cn/s/84df485efd6e安装教…

Vxe UI vue vxe-table 如何在表格中使用上传附件、上传图片

Vxe UI vue vxe-table 如何在表格中使用上传附件、上传图片 效果图 在表格中显示缩略图模式上传附件或图片 点击更多按钮查看全部 鼠标拖动上传 代码 <template><div><vxe-grid v-bind"gridOptions"></vxe-grid></div> </tem…

第九周:机器学习

目录 摘要 Abstract 一、RNN 1、引入 2、RNN的分类 二、LSTM 1、基本结构 2、具体步骤 3、举例说明 4、原理理解 总结 摘要 本周主要围绕RNN进行探讨&#xff0c;从为什么需要这类”循环网络“入手&#xff0c;提到了”slot filling“技术&#xff0c;接着又对R…