工厂方法模式 (Factory Method Pattern)

定义:

工厂方法模式(Factory Method Pattern)是一种创建型设计模式,用于解决对象创建的问题。它定义了一个创建对象的接口,但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

工厂方法模式的关键组成部分包括:

  1. 抽象创建者(Creator)
    • 定义了一个工厂方法,通常是一个抽象方法,用于创建产品对象。创建者通常包含依赖于抽象产品的代码。
  2. 具体创建者(Concrete Creator)
    • 实现了抽象创建者定义的工厂方法,用于返回一个具体产品的实例。每个具体创建者都负责创建一个特定类型的产品。
  3. 抽象产品(Product)
    • 定义了产品的接口。在抽象创建者的代码中,所有对产品的引用都使用这个接口。
  4. 具体产品(Concrete Product)
    • 实现了抽象产品定义的接口。工厂方法返回的产品实例实际上是某个具体产品对象。
解决的问题:
  • 创建对象的灵活性
    • 当一个类不知道它所必须创建的对象的类的时候。工厂方法模式允许类把实例化延迟到子类进行,这提供了更大的灵活性。
  • 产品类扩展的便利性
    • 当一个类希望由其子类来指定创建的对象时。通过定义工厂方法,子类可以覆盖这个方法以改变创建对象的类型。
  • 解耦产品的具体实现和创建过程
    • 工厂方法模式使得客户代码与产品的具体实现解耦,客户代码通过工厂接口创建产品,无需关心产品的具体实现。
  • 单一职责原则
    • 工厂方法模式可以将产品的创建职责集中到不同的工厂类中,每个工厂类负责创建一种具体产品,这符合单一职责原则。
  • 开闭原则
    • 系统更容易扩展,可以引入新的具体产品和具体工厂类,而无需修改现有代码。这符合开闭原则,即对扩展开放,对修改封闭
使用场景:
  • 不同环境下创建不同实例
    • 当对象的创建需要基于不同的环境或条件时,例如不同的配置、操作系统或者不同的资源要求。
  • 明确分离客户端和产品实现
    • 当需要明确区分客户端和产品的具体实现,使得客户端不依赖于产品实现的具体类时。
  • 单个类负责多个不同对象的创建
    • 当一个类需要创建多种类型的对象,且这些对象有共同的基类或接口时,但同时又需要保持类的职责单一。
  • 扩展产品类时避免影响客户端
    • 当系统要求提供扩展产品类的能力,而不希望这些更改影响到已有的客户端代码时。
  • 需要封装对象的创建过程
    • 当对象的创建过程需要被封装起来,以便提供更多的复用性和灵活性时。
  • 类的实例化过程复杂或有特殊要求
    • 当创建对象的过程很复杂,如涉及到复杂的初始化步骤,或者需要进行资源回收等。
示例代码:
// 产品接口
public interface Product {void use();
}// 具体产品
public class ConcreteProductA implements Product {@Overridepublic void use() {System.out.println("Using ConcreteProductA");}
}public class ConcreteProductB implements Product {@Overridepublic void use() {System.out.println("Using ConcreteProductB");}
}// 创建者/工厂接口
public interface Factory {Product createProduct();
}// 具体创建者/工厂
public class ConcreteFactoryA implements Factory {@Overridepublic Product createProduct() {return new ConcreteProductA();}
}public class ConcreteFactoryB implements Factory {@Overridepublic Product createProduct() {return new ConcreteProductB();}
}
主要符合的设计原则:
  1. 开闭原则(Open-Closed Principle):
    • 工厂方法模式非常符合开闭原则。它允许系统在不修改现有代码的情况下引入新的产品类型。当系统需要扩展新的产品时,只需要添加相应的具体工厂类和产品类即可。
  2. 单一职责原则(Single Responsibility Principle):
    • 在工厂方法模式中,每个具体工厂类只负责创建单一类型的产品。这符合单一职责原则,因为每个类都只负责一个具体的创建任务。
  3. 依赖倒转原则(Dependency Inversion Principle):
    • 工厂方法模式实现了依赖倒转原则,因为客户代码依赖于抽象接口(产品接口和工厂接口),而不是具体的类实现。这意味着客户代码并不依赖于具体的产品实例化逻辑。

工厂方法模式通过定义一个用于创建对象的接口,让子类决定实例化哪个类,从而使一个类的实例化延迟到其子类,提高了代码的灵活性和可扩展性。同时,它支持良好的封装性,客户代码仅通过接口与工厂交互,无需关心具体的产品实现细节。

在JDK中的应用:
  • java.util.Calendar
    • Calendar.getInstance() 是一个工厂方法,它根据当前的时间和默认时区返回一个 Calendar 的具体实例。此方法隐藏了具体 Calendar 子类的创建细节。
  • java.util.ResourceBundle
    • ResourceBundle.getBundle() 方法是一个工厂方法,用于根据给定的基础名和目标区域设置加载资源束。这个方法封装了资源束对象的选择和加载过程。
  • java.nio.charset.Charset
    • Charset.forName() 方法根据字符集的名称返回一个 Charset 对象。该方法是一个工厂方法,它隐藏了字符集对象的实际创建过程。
  • java.sql.DriverManager
    • 在JDBC API中,DriverManager.getConnection() 方法根据数据库URL、用户名和密码返回一个 Connection 对象。这是工厂方法模式的一个应用,它封装了数据库连接对象的创建细节。
  • java.lang.NumberFormat
    • NumberFormat 类提供了多个工厂方法(如 getNumberInstance(), getCurrencyInstance())来获取不同格式化风格的 NumberFormat 对象。
在Spring中的应用:
  • Spring的BeanFactory
    • BeanFactory 是Spring框架的核心接口,它提供了高级的配置机制来管理任何类型的对象。BeanFactory 作为一个对象工厂,它为依赖注入(DI)提供了支持,管理应用程序中定义的bean,并在需要时创建和返回bean实例。
  • ApplicationContext
    • ApplicationContextBeanFactory 的子接口,提供了更丰富的功能。它不仅用于加载Bean定义,还提供了国际化、事件传播、资源加载等其他功能。在Spring中,ApplicationContext 通常用作Bean工厂。
  • FactoryBean
    • 在Spring中,FactoryBean 接口用于定义一个Bean,它本身作为工厂来生产其他对象。这个接口允许实现类在Spring容器中定义复杂的初始化逻辑。
  • 静态工厂方法和实例工厂方法
    • Spring允许通过静态工厂方法或实例工厂方法来创建Bean。这在Spring的配置中通过 <bean> 元素的 factory-method 属性来实现。
  • ServiceLocatorFactoryBean
    • 这是一个特殊的 FactoryBean,用于定义服务定位器。它可以用来抽象对服务接口的访问,使得客户端代码不需要直接与服务实现类耦合。

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

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

相关文章

为什么要升级水经微图到64位?

前段时间&#xff0c;水经微图升级到了64位版。 这里为大家说明一下我们为什么要升级水经微图到64位。 顺便再分享一下我们在PC端产品上的一些调整。 为什么要升级到64位&#xff1f; 水经微图一直以来有一个巨大的问题&#xff0c;那就是矢量加载与绘制功能相当弱。 但凡…

SecureCRT出现Key exchange failed.No compatible key exchange method. 错误解决方法

SecureCRT出现Key exchange failed.No compatible key exchange method. 如下 Key exchange failed. No compatible key exchange method. The server supports these methods: curve25519-sha256,curve25519-sha256libssh.org,diffie-hellman-group-exchange-sha256解决方法&…

【计网 可靠数据传输RDT】 中科大笔记 (十 一)

目录 0 引言1 RDT的原理RDT的原理&#xff1a; 2 RDT的机制与作用2.1 重要协议停等协议&#xff08;Stop-and-Wait&#xff09;:连续ARQ协议: 2.2 机制与作用实现机制&#xff1a;RDT的作用&#xff1a; &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#x…

Java8 对象List 排序

目录 1.stream流式排序 1.使用说明: 2.多字段排序 2.Collections.sort(......) 排序 1.stream流式排序 Java8提供了流式操作来简化我们的编程&#xff0c;比如排序、分组、过滤、Map操作等API&#xff0c;配合Lambda表达式给我们编程带来了很大的便利&#xff0c;这篇文章重…

react高阶成分(HOC)

使用React函数式组件写了一个身份验证的一个功能&#xff0c;示例通过高阶组件实现的一个效果展示&#xff1a; import React, { useState, useEffect } from react;// 定义一个高阶组件&#xff0c;它接受一个组件作为输入&#xff0c;并返回一个新的包装组件 const withAuth…

Qt QIODevice介绍

作者:令狐掌门 技术交流QQ群:675120140 csdn博客:https://mingshiqiang.blog.csdn.net/ 文章目录 主要功能用法示例读取数据写入数据使用数据流基于套接字的读写注意事项QIODevice 是 Qt 中所有输入/输出设备的抽象基类。它为派生类提供了一组标准的接口用于读写数据。这些派…

Linux中tar命令的几个高级用法

在Linux世界中&#xff0c;Tar命令是一把解密归档世界的魔法工具。无论是打包、压缩还是解压&#xff0c;Tar命令都能胜任。本文将生动地介绍Tar命令的基本用法&#xff0c;并深入探讨五个常用选项&#xff0c;帮助读者在Linux系统中灵活运用这个强大的工具。 一、命令概述 Ta…

网络安全面试经历

2023-11-22 X亭安全服务实习生面试 一面&#xff1a; 工作方向&#xff1a;偏蓝队 总结&#xff1a;实习蓝队面试没有什么难度&#xff0c;没有什么技术上的细节问题&#xff0c;之前准备的细节问题没有考 最后和面试官聊了聊对网安的认识&#xff0c;聊了聊二进制的知识…

日本服务器访问速度和带宽有没有直接关系?

​  对于许多网站和应用程序来说&#xff0c;服务器的访问速度是至关重要的。用户希望能够快速加载页面、上传和下载文件&#xff0c;而这些都与服务器的带宽有关。那么&#xff0c;日本服务器的访问速度和带宽之间是否存在直接关系呢? 我们需要了解什么是带宽。带宽是指网络…

软件工程导论复习

文章目录 第一章软件工程学概述第二章可行性分析第三章需求分析第五章总体设计第六章详细设计第七章 实现第八章 维护重点预测 第一章软件工程学概述 什么叫软件危机&#xff1f;软件危机的表现有哪些&#xff1f;产生软件危机的原因是什么&#xff1f;什么是软件工程&#xf…

MySQL的体系结构与SQL的执行流程

文章目录 前言体系结构SQL语句的执行流程1、连接MySQL2、查询缓存3、解析SQL语句4、优化SQL语句5、执行SQL语句 总结 前言 如果你在使用MySQL时只会写sql语句的&#xff0c;那么你应该看一下《MySQL优化的底层逻辑》。如果你只了解到sql是如何优化的&#xff0c;那么你应该通过…

面试:云计算相关

文章目录 什么是云计算&#xff0c;它有哪些特性介绍一下云计算中的多租户技术&#xff0c;以及它在云环境中的应用解释一下什么是无服务器计算&#xff0c;以及它在云环境中的应用介绍一下云计算中的冷启动、热迁移和容灾&#xff0c;以及它们的优缺点描述一下云计算的几种服务…

Java反射调用kotlin中的类,Object类,Companion对象

Java反射调用kotlin中的类&#xff0c;Object类&#xff0c;Companion对象 1. Java反射调用kotlin中的普通类 kotlin普通类&#xff1a; package com.common; class TestNormal {fun get():String{return "Nolmal abc"}fun showNum(v:Int){println("Nolmal s…

【数据结构】什么是栈?

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 目录 &#x1f4cc;栈的定义 &#x1f4cc;元素进栈出栈的顺序 &#x1f4cc;栈的抽象数据类型 &#x1f4cc;栈的顺序存储结构 &#x1f4cc;栈的链式存储结构 链栈的进…

java集合,ArrayList、LinkedList和Vector,多线程场景下如何使用 ArrayList

文章目录 Java集合1.2 流程图关系1.3 底层实现1.4 集合与数组的区别1.4.1 元素类型1.4.2 元素个数 1.5 集合的好处1.6 List集合我们以ArrayList集合为例1.7 迭代器的常用方法1.8 ArrayList、LinkedList和Vector的区别1.8.1 说出ArrayList,Vector, LinkedList的存储性能和特性1.…

汽车电子 -- 根据DBC解析CAN报文

采集的CAN报文&#xff0c;怎么通过DBC解析呢&#xff1f;有一下几种方法。 首先需要确认是CAN2.0 还是CAN FD报文。 还有是 实时解析 和 采集数据 进行解析。 一、CAN2.0报文实时解析&#xff1a; 1、CANTest工具 使用CAN分析仪 CANalyst-II&#xff0c;采集CAN报文。 使用…

Python与设计模式--单例模式

Python与设计模式–单例模式 一、总线 总线是计算机各种功能部件或者设备之间传送数据、控制信号等信息的公共通信解决方案之一。 现假设有如下场景&#xff1a;某中央处理器&#xff08;CPU&#xff09;通过某种协议总线与一个信号灯相连&#xff0c;信号灯有64种颜色可以设…

JSP EL 通过 三元运算符 控制界面 标签 标签属性内容

然后 我们来说说 EL配合三元运算符的妙用 我们先这样写 <% page contentType"text/html; charsetUTF-8" pageEncoding"UTF-8" %> <%request.setCharacterEncoding("UTF-8");%> <!DOCTYPE html> <html> <head>&l…

C#8.0中新语法“is {}“的介绍及使用

一&#xff64;C#7.0及之前is的使用 is操作符检查表达式的结果是否与给定类型兼容&#xff0c;或者(从c# 7.0开始)根据模式测试表达式。有关类型测试is操作符的信息&#xff0c;请参阅类型测试和类型转换操作符文章的is操作符部分。 1&#xff64;is 模式匹配 从C&#xff0…

推荐一个静态页面生成网站,可以快速生成一个文档页面

vitepress VitePress | Vite & Vue Powered Static Site Generator