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

news2024/11/17 4:22:25

1. 简单工厂模式定义

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

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

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

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

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

2.1 相关代码实现

package simple_factory_pattern


// 产品接口
type Pizza interface {
    MakePizza()
}

package simple_factory_pattern

import "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_pattern

import "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_pattern

import "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_pattern

import "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 main

import (
    "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.coloradmin.cn/o/2088093.html

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

相关文章

认识Kubebuilder

认识Kubebuilder 一、什么是Kubebuilder?Kubebuilder,K8s operator创建框架controller-runtime和controller-tools库 二、Kubebuilder,举例来说开源项目kuik 三、使用 kubebuilder init 创建基础项目四、使用kubebuilder create api生成控制器CachedIma…

gitea仓库迁移新服务器 更新远程仓库地址(git remote remove origin)

文章目录 引言I 镜像部署方式迁移案例迁移容器备份gitea服务器配置II 修改​远程仓库地址set-url语法案例III 扩展基于git命令方式进行代码迁移忽略被追踪的文件(update .gitignore)see also引言 由于部署git仓库的机器不稳定,决定进行服务器迁移。更新远程仓库地址的应用场景…

传统助贷机构如何利用CRM系统转型升级

传统助贷机构在利用CRM系统(客户关系管理系统)进行转型升级时,可以遵循以下几个关键步骤和策略,以优化客户管理、提升业务效率并实现业务增长: 一、明确转型升级目标 首先,传统助贷机构需要明确利用CRM系统…

使用docker compose一键部署 Openldap

使用docker compose一键部署 Openldap LDAP(轻量级目录访问协议,Lightweight Directory Access Protocol)是一种用于访问分布式目录服务的网络协议,OpenLDAP 是 LDAP 协议的一个开源实现,由 OpenLDAP 项目提供&#x…

python库(21):TextBlob库实现文本处理

1 TextBlob简介 TextBlob 是一个基于 Python 的文本处理库,能够让基础的自然语言处理任务变得异常简单。 它提供了一个简单直观的 API,让你能够轻松执行词性标注、名词短语提取、情感分析、文本分类和关键词提取等功能。 值得一提的是,Tex…

Linux git的基本使用 安装 提交

目录 安装git 首次使用git的配置 拉取仓库 步骤1:新建仓库 步骤2:复制仓库地址 步骤3:远端仓库拉取到本地 上传代码 常用指令 安装git sudo apt-get install git # Ubuntu/Debian sudo dnf install git # Fedora sudo yum insta…

BMS中内阻补偿的使用

在BMS(电池管理系统)中,内阻补偿的使用主要涉及以下几个步骤和方法: 1. 内阻测量 实时监测:通过专用电路或算法实时测量电池的内阻。常用的方法包括脉冲测试法和交流阻抗测试法。计算内阻:基于电流和电压…

基于AI+多技术融合在流域生态系统服务评价 制图、水资源水环境水生态分析、土壤侵蚀分析、流域产水分析、流域碳收支评估、气候变化影响等应用

流域生态系统服务在环境保护与资源管理中具有不可替代的重要性。随着全球气候变化和人类活动对自然环境的压力日益增大,流域生态系统的稳定性和健康状况面临严峻挑战。水资源短缺、洪水频发、水质污染、生物多样性减少等问题,正在威胁流域内及其下游区域…

【综合架构】Part 5.2 Ansible

安装设备:管理设备-m01-10.0.0.61 部署与配置 部署 yum install -y ansible 配置 步骤 1:修改配置文件:关闭Host_key_checking。 vim /etc/ansible/ansible.cfg 步骤 2:修改配置文件:开启日志功能。

作为HR如何解决候选人爽约的问题

为了降低候选人的爽约概率,HR可以直接在预约面试时,通过电话或短信等多种方式,与候选人进行沟通,确保对方完全清楚面试的时间、地点和流程。在双方沟通的过程中,HR一定要注意语气亲切,要让候选人感受到企业…

2020年中国海岸带10m土地覆盖图

2020年中国海岸带10m土地覆盖遥感图 数据介绍 土地利用/覆盖分类是研究海岸带动态变化过程、理解滨海社会-生态系统作用机制和支持可持续发展的重要基础。中国海岸带土地覆盖复杂多样,以往多类别地表覆盖和滨海湿地专题数据集难以兼顾陆域和海域信息,而…

软考攻略/超详细/系统集成项目管理工程师/基础知识分享07

第三章 信息技术服务 3.1 内涵与外延 3.1.1 服务的特征(掌握) 服务的特征包括:无形性、不可分离性、可变性和不可储存性等。 3.1.2 IT服务的内涵(掌握) IT服务除了具备服务的基本特征,还具备本质特征、形…

利用C++实现PCL点云可视化:示例程序及解析(持续更新)

【版权声明】本文为博主原创文章,未经博主允许严禁转载,我们会定期进行侵权检索。 参考书籍:《人工智能点云处理及深度学习算法》 本文为专栏《Python三维点云实战宝典》系列文章,专栏介绍地址“【python三维深度学习】python…

HTML <template> 标签的基本技巧

前言 HTML中的<template>标记是 Web 开发中一个功能强大但经常未得到充分利用的元素。它允许你定义可重复使用的内容&#xff0c;这些内容可以克隆并插入 DOM 中而无需最初渲染。 此功能对于创建动态、交互式 Web 应用程序特别有用。 在本文中&#xff0c;我们将探讨有…

二极管、电阻、电容、电感的种类及作用

系列文章目录 文章目录 系列文章目录前言二极管的种类二极管的作用电容的种类电容的作用电阻的作用电感的作用 前言 参考&#xff1a;这个UP的视频&#xff1a;8位和32位单片机最本质区别&#xff0c;2分钟看懂&#xff01; 二极管的种类 1.恒流二极管&#xff1a;可以用在恒…

微积分复习笔记 Calculus Volume 1 - 1.2 Basic Classes of Functions

1.2 Basic Classes of Functions - Calculus Volume 1 | OpenStax

NetApp AFF A 全闪存系列,专为 AI 时代打造的统一数据存储

NetApp AFF A 系列系统可轻松为要求最苛刻的工作负载提供动力支持&#xff0c;从当前运行业务的任务关键型应用程序到未来将释放创新潜能和工作效率的 AI 和 GenAI 工作负载。凭借 GenAI 和其他现代企业业务负载所迫切需要的高级数据管理能力、行业领先的勒索软件防范技术和云集…

antd vue switch组件怎么把值true、false改为uint32类型的1和0

背景 已知switch组件的checked属性默认是传入true 和 false的&#xff0c;但是有这样的业务情景&#xff0c;既需要使用的是开关&#xff0c;又需要传入的是整数&#xff0c;那么我们应该如何修改呢&#xff1f; 解决方案 <a-form-item label"允许失败时保存"&…

视频压缩怎么操作?三个办法教你无损压缩视频

随着假期的结束&#xff0c;很多同学和朋友们开始整理自己在假期期间拍摄的各种视频&#xff0c;准备分享到社交媒体或是保存到自己的移动设备上。 然而&#xff0c;面对高清甚至4K视频的大文件体积&#xff0c;不少人都会遇到存储空间不足的问题。这时候&#xff0c;一个好的…

完全二叉树的表示转换:从邻接链表到邻接矩阵

完全二叉树的表示转换:从邻接链表到邻接矩阵 摘要一、引言二、完全二叉树的特点三、邻接链表到邻接矩阵的转换四、C代码实现五、结果分析六、结论摘要 在数据结构中,树是一种重要的非线性数据结构,用于表示具有层次关系的数据。树的表示方法主要有两种:邻接链表和邻接矩阵…