设计模式-简单工厂模式工厂方法模式

1. 简单工厂模式定义

        简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,它通过专门定义一个类来负责创建其他类的实例,这个类通常被称为工厂类简单工厂模式并不是一种正式的设计模式,但它确实是一种常用的编程技巧。

        在简单工厂模式中,工厂类包含了一个方法,这个方法根据传入的参数来决定创建哪种具体对象,并返回这个对象的实例。这样做的好处是,将对象创建的逻辑集中管理,客户端代码不需要直接实例化对象,而是通过工厂方法来获取所需的对象。

从上面的定义中可以看出,简单工厂模式包含以下三个部分:

  1. 工厂:负责实现创建所有产品的逻辑,可以说是在这个工厂里面可以实例化所有相关的类;
  2. 产品接口:这里面封装了所有产品的公共方法,这也是一类产品的特性,比如披萨制作过程都会包括:切等等。
  3. 具体产品:一般就是会实现产品接口里面所用公共方法的产品。比如奶酪披萨,素食披萨,他们的制作过程是差不多的,所以都会实现制作披萨这个公共方法。

2. 简单工厂模式UML图表示

2.1 相关代码实现

package simple_factory_pattern// 产品接口
type Pizza interface {MakePizza()
}package simple_factory_patternimport "fmt"// 具体产品---奶酪披萨
type CheesePizza struct{}func NewCheesePizza() *CheesePizza {return &CheesePizza{}
}func (c *CheesePizza) Prepare() {fmt.Println("Prepare Cheese Pizza")
}func (c *CheesePizza) Bake() {fmt.Println("Bake Cheese Pizza")
}func (c *CheesePizza) Cut() {fmt.Println("Cut Cheese Pizza")
}func (c *CheesePizza) Box() {fmt.Println("Box Cheese Pizza")
}func (c *CheesePizza) MakePizza() {c.Prepare()c.Bake()c.Cut()c.Box()
}package simple_factory_patternimport "fmt"// 具体产品2---素食披萨
type VeggiePizza struct{}func NewVeggiePizza() *VeggiePizza {return &VeggiePizza{}
}func (v *VeggiePizza) Prepare() {fmt.Println("Prepare Veggie Pizza")
}func (v *VeggiePizza) Bake() {fmt.Println("Bake Veggie Pizza")
}func (v *VeggiePizza) Cut() {fmt.Println("Cut Veggie Pizza")
}func (v *VeggiePizza) Box() {fmt.Println("Box Veggie Pizza")
}func (v *VeggiePizza) MakePizza() {v.Prepare()v.Bake()v.Cut()v.Box()
}package simple_factory_pattern// 披萨工厂,专门用来实例化pizza对象
type PizzaFactory struct{}// CreatePizza creates a pizza based on the pizzaType
func (p *PizzaFactory) CreatePizza(pizzaType string) Pizza {switch pizzaType {case "cheese":return NewCheesePizza()case "veggie":return NewVeggiePizza()default:return nil}
}

2.2 优缺点

简单工厂模式的优点包括:

  • 客户端代码与具体类的实现解耦,便于后期的扩展和维护。

  • 中央化了对象创建的逻辑,使代码更易读、更易管理。

缺点包括:

  • 工厂类集中了所有实例创建的逻辑,可能会导致该类变得过于复杂

  • 增加新的产品类型时需要修改工厂类的代码,违背了开闭原则(对扩展开放,对修改关闭)。

3. 工厂方法模式

        为了不违背开闭原则,因此有了工厂方法模式。在每次新增产品类型的时候,把对工厂类的修改放到了客户端进行判断,不需要再改变工厂类,从而不会违背开闭原则。

        工厂方法模式是一种创建型模式,它通过定义一个创建对象的接口,让子类决定实例化哪一个类。工厂方法模式让一个类的实例化延迟到其子类。在工厂方法模式中,每个具体产品都有一个对应的具体工厂来创建。下面是将简单工厂模式改写成工厂方法模式的实现:

  1. 首先定义一个 Pizza 接口及其实现类。

  2. 然后为每个具体的 Pizza 类定义一个具体的工厂类,这些工厂类实现一个共同的 PizzaFactory 接口。

 3.1 UML图表示

3.2 相关代码实现

// 产品接口
package factory_method_pattern// 产品接口type Pizza interface {MakePizza()
}// 具体产品实现--奶酪披萨package factory_method_patternimport "fmt"
// 具体产品---奶酪披萨type CheesePizza struct{}func NewCheesePizza() *CheesePizza {return &CheesePizza{}
}func (c *CheesePizza) Prepare() {fmt.Println("Prepare Cheese Pizza")
}func (c *CheesePizza) Bake() {fmt.Println("Bake Cheese Pizza")
}func (c *CheesePizza) Cut() {fmt.Println("Cut Cheese Pizza")
}func (c *CheesePizza) Box() {fmt.Println("Box Cheese Pizza")
}func (c *CheesePizza) MakePizza() {c.Prepare()c.Bake()c.Cut()c.Box()
}// 具体产品实现2---素食披萨
go复制代码
package factory_method_patternimport "fmt"
// 具体产品---素食披萨type VeggiePizza struct{}func NewVeggiePizza() *VeggiePizza {return &VeggiePizza{}
}func (v *VeggiePizza) Prepare() {fmt.Println("Prepare Veggie Pizza")
}func (v *VeggiePizza) Bake() {fmt.Println("Bake Veggie Pizza")
}func (v *VeggiePizza) Cut() {fmt.Println("Cut Veggie Pizza")
}func (v *VeggiePizza) Box() {fmt.Println("Box Veggie Pizza")
}func (v *VeggiePizza) MakePizza() {v.Prepare()v.Bake()v.Cut()v.Box()
}// 工厂接口
package factory_method_pattern// 工厂接口
type PizzaFactory interface {CreatePizza() Pizza
}// 奶酪披萨工厂
package factory_method_pattern// 奶酪披萨工厂
type CheesePizzaFactory struct{}func NewCheesePizzaFactory() *CheesePizzaFactory {return &CheesePizzaFactory{}
}func (c *CheesePizzaFactory) CreatePizza() Pizza {return NewCheesePizza()
}// 素食披萨工厂
package factory_method_pattern// 素食披萨工厂type VeggiePizzaFactory struct{}func NewVeggiePizzaFactory() *VeggiePizzaFactory {return &VeggiePizzaFactory{}
}func (v *VeggiePizzaFactory) CreatePizza() Pizza {return NewVeggiePizza()
}// 使用实例
package mainimport ("fmt"    "factory_method_pattern"
)func main() {var factory factory_method_pattern.PizzaFactory// 使用 CheesePizzaFactory 创建 CheesePizza    factory = factory_method_pattern.NewCheesePizzaFactory()cheesePizza := factory.CreatePizza()cheesePizza.MakePizza()// 使用 VeggiePizzaFactory 创建 VeggiePizza    factory = factory_method_pattern.NewVeggiePizzaFactory()veggiePizza := factory.CreatePizza()veggiePizza.MakePizza()
}

  在这个实现中,每个具体的披萨工厂都实现了 PizzaFactory 接口,并提供了自己的 CreatePizza 方法。这样,客户端代码可以根据需要选择不同的工厂来创建不同的披萨对象,而不需要直接依赖具体的披萨类。这种设计使得系统更灵活,更容易扩展。不会违背开闭原则 


http://www.ppmy.cn/server/107998.html

相关文章

一个非常实用的Win系统瘦身项目,PowerShell脚本支持Windows 11跟10,非常轻量好用(附源码)

Win经常我们都经常用,但系统里总是预装了一些我们可能并不需要的应用程序。这些应用不仅占用了宝贵的存储空间,还可能拖慢了我们的电脑速度。特别是Windows 11,一些花里胡哨的功能和后台服务,让我们的电脑变得不那么“清爽”。 今…

react面试题六

一、React中如何捕获和处理错误? 在React中,捕获和处理错误是一个重要的部分,以确保应用的健壮性和用户体验。React提供了几种机制来捕获和处理错误,包括错误边界(Error Boundaries)、事件处理器中的try/ca…

空气净化器怎么选?有为养宠家庭专门设计的空气净化器吗

如今养宠已经成为一个新的热潮,不少人开始养猫养狗,上到六七十岁的空巢老人,下到在校读书的大学生,十个人里面起码是有两三个在养猫养狗的,包括我这个在上了几年班的上班族。之前在学校的时候就想养狗,但是…

设计一个算法,用最少的时间在顺序表中找到x,若找到,与后继交换,找不到插入到顺序表中,任保持有序。

题目:线性表(a1,a2.........an)中的元素递增有序且按照顺序存储在计算机中。设计一个算法,用最少的时间在顺序表中查找数值为x的元素,若找到,则将其与后继元素位置相交换,若找不到,将…

验证框架FluentValidation在C# 中的应用

FluentValidation在C#中的应用非常广泛,它作为一个基于.NET开发的验证框架,用于构建强类型验证规则的.NET库。以下是FluentValidation在C#中的几个主要应用方面: 目录 1. 验证规则的定义 2. 跨平台支持 3. 与MVC、Web API等框架的集成 4…

【C语言篇】

C语言是一种广泛使用的计算机编程语言,它以其高效、灵活和功能强大而著称。以下是一些C语言中的常见知识点: 基本语法: 变量声明与初始化 数据类型(整型、浮点型、字符型等) 控制语句(if、for、while、do…

MySQL常用函数

日期函数 -- 日期,字符串,数值函数 -- 1.获取系统当前日期、时间 select now(),curdate(),curtime(),sysdate(),current_timestamp(),CURRENT_DATE(); -- 2.星期DAYOFWEEK:星期日是1;weekday:星期日是6 dayname单词 se…

Oracle(89) 什么是等待事件(Wait Event)?

等待事件(Wait Event)是数据库系统中一个关键的性能指标,用于描述会话在执行SQL语句过程中等待某些资源或者条件的时间。这些等待事件可以帮助数据库管理员(DBA)识别和诊断性能瓶颈,从而采取相应措施优化数…

SpringMVC工作原理(荣耀典藏版)

目录 前言 一、SpringMVC简介 二、SpringMVC流程 三、组件说明 3.1.组件 四、MVC模式 前言 大家好,我是月夜枫~~ 今天和大家来分享一下SpringMVC工作原理,首先我们先来了解一下SpringMVC的作用以及使用方式。 一、SpringMVC简介 Spring MVC属于…

【C#】【EXCEL】BumblebeeComponentsAnalysisGH_Ex_Ana_CondScale.cs

这段代码定义了一个名为 GH_Ex_Ana_CondScale 的类,它是一个 Grasshopper 组件,用于在 Excel 工作表中添加基于相对值的条件格式颜色。以下是该组件的主要功能和介绍: 功能概述: 这个组件用于在 Excel 中为指定范围的单元格添加条…

数据库:笔记01绪论

基本概念 数据(Data) 描述事物的符号记录称为数据,并且可以数字化存入计算机。 数据的含义称为数据的语义,数据与其语义是不可分的。 数据库(DataBase,DB) 存放数据的仓库 数据库数据具有永久存储、有…

08--kubernetes可视化界面与Daemonset

前言:前几章写的内容太多了,后面打算写k8s持久化篇幅也不小,这一章算作过度章节,内容简单一些,主要是K8S_web界面与Daemonset控制器。 1、Dashboard Dashboard是一个图形化界面,用于汇总和展示来自不同数…

深入理解Seaborn库的高级功能(二)

Seaborn作为Python中一个功能强大的可视化库,建立在matplotlib的基础之上,提供了更高级的API,使得数据可视化的创建过程更为简便和直观。在实际的数据分析工作中,Seaborn不仅可以帮助我们快速绘制高质量的图表,还能通过丰富的图形种类和调色板选项,让数据展示更加生动、清…

为什么收录是做谷歌seo的前提?

如果谷歌没有收录你的网站,基本上你就不存在于谷歌的搜索结果中,无论别人怎么做,在谷歌里,用户就不可能知道你网站的存在 收录是谷歌了解你网站内容的第一步,通过收录,谷歌可以开始分析你的网站内容&#…

基于xr-frame实现微信小程序的人脸识别3D模型叠加AR功能(含源码)

前言 xr-frame是一套小程序官方提供的XR/3D应用解决方案,基于混合方案实现,性能逼近原生、效果好、易用、强扩展、渐进式、遵循小程序开发标准。xr-frame在基础库v2.32.0开始基本稳定,发布为正式版,但仍有一些功能还在开发&#…

微服务间调用

一、restTemplate 1、先将restTemplate注册成为一个bean Configuration public class RemoteCallConfig {Beanpublic RestTemplate restTemplate() {return new RestTemplate();} }2、实现代码 private void handleCartItems(List<CartVO> vos) {// TODO 1.获取商品id…

LuaJit分析(六)luajit -bl 命令分析

Luajit -bl命令用于将luajit字节码文件或者lua脚本文件反汇编&#xff0c;输出汇编指令&#xff0c;很好奇怎么将字节码文件和lua脚本文件放在一块处理的&#xff0c;下面一步步分析&#xff1a; luajit虚拟机由luajit.c文件生成&#xff0c;首先定位到main函数&#xff0c;代…

深入浅出神经网络-学习小结

神经网络识别手写数字 基础知识 如何理解感知机 激活函数是阶跃函数的神经元 sigmoid作用 阶跃函数的升级&#xff0c;平滑了阶跃函数&#xff0c;阶跃函数不容易稳定&#xff0c;sigmoid克服了此缺点 多层感知机 可以理解为多层sigmoid激活函数神经元连接的网络 前馈神经…

C语⾔内存函数

文章目录 1.memcpy使用和模拟实现memcpy的使用&#xff1a;memcpy的模拟实现&#xff1a; 2.memmove使用和模拟实现memmove的使用:memmove的模拟实现&#xff1a; 3. memset函数的使⽤4.memcmp函数的使用 1.memcpy使用和模拟实现 void * memcpy ( void * destination, const v…

Python(PyTorch)多语言图像感知质量指标算法

&#x1f3af;要点 &#x1f3af;算法实现&#xff1a;&#x1f58a;PyTorch单尺度和多尺度质量指标算法 | &#x1f58a;C单尺度质量指标算法 | &#x1f58a;Rust多尺度质量指标算法 | &#x1f58a;LabVIEW单尺度质量指标算法 | &#x1f58a;MATLAB单尺度质量指标算法 | &…