软件设计模式------工厂方法模式

工厂方法模式(Factory Method Pattern),又称工厂模式,也叫虚拟构造器模式(Virtual Constructor Pattern)或多态工厂模式(Polymorphic Pactory Pattern),属于类创建型模式。

        我们知道简单工厂模式最大的缺点就是当有新产品要加入到系统中时,必须修改工厂类,加入必要的处理逻辑,这违背了“开闭原则”。

        并且在简单工厂模式中,所有的产品都是由同一个工厂创建,则造成了工厂类职责较重,业务逻辑较为复杂,具体产品与工厂类之间的耦合度高,严重影响了系统的灵活性和扩展性。

一、模式动机:

        考虑到这样一个系统,一个具体工厂只生产一种具体产品。

        例如,简单工厂模式下,按钮工厂既生产圆形按钮也生产矩形按钮或其他按钮等等

        但在工厂方法模式下,我们先定义一个抽象的按钮工厂类(接口),再定义具体的工厂类来生产具体的按钮(产品),即圆形工厂只生产圆形按钮,矩形工厂只生产矩形按钮,圆形工厂和矩形工厂都实现抽象的按钮工厂接口。

***这样进行抽象化的结果使工厂模式这种结构可以在不修改具体工厂类的情况下引进新的产品

即:如果出现新的按钮类型,只需为这种新的按钮类型新建一个具体共厂类,即可获得该新按钮的实例。

二、定义:

        在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,则工厂子类负责生成具体的产品对象,即通过工厂子类来确定究竟应该实例化哪一个具体产品类

三、模式结构:

1.Product(抽象产品):

        定义产品的接口。

2.ConcreteProduct(具体产品):

        实现抽象产品接口。

3.Factory(抽象工厂):

        声明工厂方法,用于返回一个产品。

4.ConcreteFactory(具体工厂):

        实现抽象工厂的工厂方法,并可由客户调用,返回一个具体产品类的实例。

四、模式分析:

        具体工厂类都具有共同的接口,或者有共同的抽象父类。当系统扩展需要添加新的产品时,仅仅需要添加一个具体产品对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也无需修改客户端,很好地符合了“开闭原则”。

五、模式实例与解析:

1.实例说明

        在某网络管理软件中,需要为不同的网络协议提供不同的连接类,例如针对POP3协议的连接类POP3Connection,针对IMAP协议的连接类IMAPConnection,针对HTTP协议的连接类HTTPConnection,由于网络连接对象的创建过程较为复杂,需要将其创建过程封装到专门的类中,该软件还将支持更多类型的网络协议。现采用工厂方法模式进行设计,绘制类图并编程模拟实验。

2.实例类图

3.实例代码

(产品区 Products包)

(1)Connection接口

package Products;public interface Connection {public void connect();
}

(2)HTTPConnection类

package Products;public class HTTPConnection implements Connection{@Overridepublic void connect() {System.out.println("Connecting HTTP ...");}
}

(3)IMAPConnection类

package Products;public class IMAPConnection implements Connection{@Overridepublic void connect() {System.out.println("Connecting IMAP ...");}
}

(4)POP3Connection类

package Products;public class POP3Connection implements Connection{@Overridepublic void connect() {System.out.println("Connecting POP3 ...");}
}

(工厂区 Factories包)

(1)ConnectionFactory接口

package Factories;import Products.Connection;public interface ConnectionFactory {public Connection create();
}

(2)HTTPFactory类

package Factories;import Products.Connection;
import Products.HTTPConnection;public class HTTPFactory implements ConnectionFactory{@Overridepublic Connection create() {return new HTTPConnection();}
}

(3)IMAPFactory类

package Factories;import Products.Connection;
import Products.IMAPConnection;public class IMAPFactory implements ConnectionFactory{@Overridepublic Connection create() {return new IMAPConnection();}
}

(4)POP3Factory类

package Factories;import Products.Connection;
import Products.POP3Connection;public class POP3Factory implements ConnectionFactory{@Overridepublic Connection create() {return new POP3Connection();}
}
4.辅助代码

(1)XMLUtil类

(Clients包下)

package Clients;import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;
public class XMLUtil
{//该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象public static Object getBean(){try{//创建文档对象DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = dFactory.newDocumentBuilder();Document doc;doc = builder.parse(new File("FactoryMethodconfig.xml"));//获取包含类名的文本节点NodeList nl = doc.getElementsByTagName("className");Node classNode=nl.item(0).getFirstChild();String cName=classNode.getNodeValue();//通过类名生成实例对象并将其返回Class c=Class.forName(cName);Object obj=c.newInstance();return obj;}catch(Exception e){e.printStackTrace();return null;}}
}

(2)客户端测试类 Client类

(在Clients包下)

package Clients;import Factories.ConnectionFactory;
import Factories.HTTPFactory;
import Products.Connection;public class Client {public static void main(String[] args) {ConnectionFactory factory;Connection connection;factory = (ConnectionFactory) XMLUtil.getBean();connection = factory.create();connection.connect();}
}

(3)配置文件FactoryMethodconfig.xml

(路径放在工程下面)

<?xml version="1.0"?>
<config><className>Factories.HTTPFactory</className>
</config>
5.实例结果与分析

(1)如果将配置文件FactoryMethodconfig.xml中的<className>里的内容改为Factories.IMAPFactory(包名.具体工厂类),则运行结果如下:

(2)如果将配置文件FactoryMethodconfig.xml中的<className>里的内容改为Factories.POP3Factory,则运行结果如下:

(3)分析:在系统中加入一个新产品时,只需添加一个具体工厂类和一具体产品类即可。

六、模式的优点

        1、在工厂方法模式中,工厂方法用来用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关系具体产品所对应的工厂,无需关心创建细节,甚至无需知道具体产品类的类名。

        2、所有的工厂具体类都具有同一抽象工厂父类。

        3、在系统中加入一个新产品时,只需添加一个具体工厂类和一具体产品类即可。而无需修改抽象工厂类和抽象产品类的接口。如此便完全符合了”开闭原则“。

七、模式的缺点

        1、在系统中加入一个新产品时,只需添加一个具体工厂类和一具体产品类即可,但随着新产品数量的增加,类的数量也随着增加,则在一定程度增加了系统的复杂度,另外更多的类需要编译和运行,会给系统带来一些额外的开销。

        2、由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用了抽象层进行了定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。

八、模式适用环境

        (1)一个类(客户端,即测试类)不知道它所需要的对象的类(具体产品类类名),只需知道对应的具体工厂类类名即可。

        (2)将创建对象的任务委托给多个工厂子类的某一个,客户端在使用时无需关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体产品类的类名存储在配置文件或数据库中。

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

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

相关文章

Spring数据源对象管理:基于XML配置文件的第三方bean管理

前言 第三方资源配置管理 ioc容器和依赖管理&#xff0c;我们大多数管理的是自己创建的bean&#xff0c;如果是第三方提供的bean是如何管理&#xff0c;我们以数据源对象的ioc管理为例子进行说明。 步骤 第一步&#xff1a; 需要导入相应的依赖包&#xff08;导入坐标&#xf…

解构OpenAI swarm:利用Cursor进行框架分析与示例运行

解构OpenAI SWARM:利用Cursor进行框架分析与示例运行 1. 引言 在AI技术日新月异的今天,OpenAI再次为我们带来了惊喜。SWARM框架作为其最新研究成果,正在开创多智能体协作的新纪元。本文将带您深入探索这一框架,通过Cursor工具进行代码分析,并手把手教您安装运行SWARM。无论您…

Data+AI下的数据湖和湖仓一体发展史

DataAI下的数据湖和湖仓一体发展史 前言数据湖的“前世今生”AI时代的救星&#xff1a;湖仓一体湖仓一体实践演进未来趋势&#xff1a;智能化、实时化结语 前言 数据湖&#xff1f;湖仓一体&#xff1f;这是什么高科技新名词&#xff1f; 别急&#xff0c;我们慢慢聊。想象一…

机器学习:opencv--风格迁移

目录 前言 一、代码及步骤解释 1.图片与处理 2.加载模型 3.输出图像 前言 风格迁移&#xff08;Style Transfer&#xff09;是一种计算机视觉技术&#xff0c;旨在将一种图像的艺术风格应用到另一种图像上&#xff0c;同时保持其内容。 一、代码及步骤解释 1.图片与处理 …

从Apple Intelligence到远程机器人手术:更快、更安全的网络成企业业务关键

过去&#xff0c;企业的业务模式和网络架构相对简单&#xff0c;数据传输量不大&#xff0c;远程访问需求也不多。企业对网络的要求主要集中在确保基本的连通性和可用性。如今&#xff0c;企业通过将产品与各项高新技术深度融合&#xff0c;赋予传统产品活力和竞争力。以苹果公…

web3D越来越普及来,在站显示效果上没说的

Web3D 技术为网站带来了全新的视觉体验。它能够以逼真的三维形式展示产品、场景或数据&#xff0c;让用户仿佛身临其境。 无论是展示复杂的机械结构、精美的艺术品&#xff0c;还是模拟真实的自然环境&#xff0c;Web3D 都能以其出色的表现力吸引用户的注意力。 在显示效果上…

国产大模型基础能力大比拼 - 计数:通义千文 vs 文心一言 vs 智谱 vs 讯飞-正经应用场景的 LLM 逻辑测试

在大语言模型&#xff08;LLM&#xff09;不断涌现的时代&#xff0c;如何评估这些国产大模型的逻辑推理能力&#xff0c;尤其是在处理基础计数问题上的表现&#xff0c;成为了一个备受关注的话题。随着越来越多的国产大模型进入市场&#xff0c;比较它们在不同任务中的表现尤为…

mysql数据同步ES方案---DTS

在上一篇文章中&#xff0c;我通过一个简单的例子实现了如何通过 Canal 实现 MySQL 数据到 Elasticsearch 的同步&#xff0c;以满足增量捕获和实时同步的需求。然而实际情况中&#xff0c;比如在我之前工作的公司&#xff0c;为了减少运维工作量和代码操作的复杂性&#xff0c…

Android OpenGL粒子特效

在本篇&#xff0c;我们将开启一个新的项目&#xff0c;探索粒子的世界。粒子是一种基本的图形元素&#xff0c;它们通常被表示为一组点。通过巧妙地组合一些基础的物理效果&#xff0c;我们能够创造出许多令人惊叹的视觉效果。想象一下&#xff0c;我们可以模拟一个水滴从喷泉…

Xcode使用Instruments的dsym还原符号堆栈问题

文章目录 设置符号表的步骤参考资料 设置符号表的步骤 instruments 的 Settings 中&#xff0c;可以设置符号表的搜索路径 没有生效的话&#xff0c;继续看 File 里面的 Symbols - 出现弹窗后点击 Add Symbols - 然后再点击 Apply。 参考资料 https://xjkstar.github.i…

Unity URP shader ———魔系符文宝石是如何练成的

各位同学大家好 我已经很久没有没有写教程了&#xff0c;最近项目比较忙。各种加班各种带小孩儿&#xff0c;不过&#xff0c;老师一有机会也在给尽可能服务大家&#xff0c;今天来一个硬菜&#xff1a;移动端高效魔系符文如何制作&#xff0c;国庆起来&#xff0c;老师抽了点…

汽车免拆诊断案例 | 2013款宝马116i车偶尔加速不良

故障现象  一辆2013款宝马116i车&#xff0c;搭载N13B16A 发动机&#xff0c;累计行驶里程约为12.1万km。车主反映&#xff0c;该车行驶中偶尔加速无反应&#xff0c;且发动机故障灯异常点亮。 故障诊断 接车后试车&#xff0c;故障现象无法再现。用故障检测仪检测&#xff…

RestClient查询文档match查询、精确查询和布尔查询

目录 match查询 精确查询 布尔查询 match查询 全文检索的match和multi_match查询与match_all的API基本一致。差别是查询条件&#xff0c;也就是query的部分。 因此&#xff0c;Java代码上的差异主要是request.source().query()中的参数了。同样是利用QueryBuilders提供的方法…

解决在Windows中安装tensorflow2.10无法检测到GPU的问题

解决在Windows中安装tensorflow2.10无法检测到GPU的问题 官方给出的Windows本地安装方式 更新显卡驱动到最新。安装anaconda或miniconda作为python环境的管理工具。创建新的环境tf&#xff1a;conda create --name tf python3.9&#xff0c;然后进入改环境&#xff1a;conda …

redis的zset实现下滑滚动分页查询思路

常规zset查询 我们redis的数据为 我们知道 我们常规查询的话 我们假如 zset 表中 有7个元素&#xff0c;然后我们进行分页查询的话&#xff0c;我们一次查3个元素&#xff0c;然后查出来元素 和元素的分数 我们redis的语法应该这样写 zrevrangebyscore wang 1000 0 withsc…

目标检测最新SOTA模型D-FINE

2024年10月18号&#xff0c;中科大推出了 D-FINE&#xff0c;这是一款功能强大的实时物体检测器&#xff0c;通过重新定义 DETR 模型中的边界框回归任务实现了出色的定位精度。 摘要 D-FINE 包含两个关键组件&#xff1a;细粒度分布细化 (FDR) 和全局最优定位自蒸馏 (GO-LSD)…

【正点原子K210连载】第四十五章 人脸识别实验 摘自【正点原子】DNK210使用指南-CanMV版指南

第四十五章 人脸识别实验 在上一章节中&#xff0c;介绍了利用maix.KPU模块实现了人脸68关键点检测&#xff0c;本章将继续介绍利用maix.KPU模块实现的人脸识别。通过本章的学习&#xff0c;读者将学习到人脸识别应用在CanMV上的实现。 本章分为如下几个小节&#xff1a; 45.1…

vue3使用element-plus手动更改url后is-active和菜单的focus颜色不同步问题

在实习&#xff0c;给了个需求做个新的ui界面&#xff0c;遇到了一个非常烦人的问题 如下&#xff0c;手动修改url时&#xff0c;is-active和focus颜色不同步 虽然可以直接让el-menu-item:focus为白色能解决这个问题&#xff0c;但是我就是想要有颜色哈哈哈&#xff0c;有些执…

车载实操:一对一实操学习、CANoe实操学习、推荐就业机会、就业技术支持、协助面试辅导

FOTA模块中OTA的知识点&#xff1a;1.测试过程中发现哪几类问题&#xff1f; 可能就是一个单键的ecu&#xff0c;比如升了一个门的ecu&#xff0c;他的升了之后就关不上&#xff0c;还有就是升级组合ecu的时候&#xff0c;c屏上不显示进度条。 2.在做ota测试的过程中&#xff…