设计模式之简单工厂模式详解

简单工厂模式

工厂模式:工厂方法模式;

低阶:简单工厂模式;

高阶:抽象工厂模式;

1)概述

定义一个工厂类,根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。

在简单工厂模式中创建实例的方法是静态(static)方法,因此简单工厂模式又被称为静态工厂方法(Static Factory Method)模式。

2)流程

1.将需要创建的对象(Chart对象)的代码封装到不同的类中,称为具体产品类;

2.将公共的代码进行抽象和提取后封装在一个抽象产品类中,每一个具体产品类都是抽象产品类的子类;

3.提供一个工厂类用于创建各种产品,在工厂类中提供一个创建产品的工厂方法,该方法可以根据所传入的参数不同创建不同的具体产品对象;

4.客户端只需调用工厂类的工厂方法并传入相应的参数即可得到一个产品对象。

在这里插入图片描述

3)角色

● Factory(工厂角色):即工厂类,负责创建所有产品实例的内部逻辑;工厂类可以被外界直接调用,创建所需的产品对象;在工厂类中提供了静态的工厂方法 factoryMethod(),返回类型为抽象产品类型 Product。

● Product(抽象产品角色):是工厂类所创建的所有对象的父类,封装了各种产品对象的公有方法,它的引入将提高系统的灵活性,使得在工厂类中只需定义一个通用的工厂方法,因为所有创建的具体产品对象都是其子类对象。

● ConcreteProduct(具体产品角色):是简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现在抽象产品中声明的抽象方法。

4)案例-初始方案

开发一套图表库,为应用系统提供不同外观的图表,例如柱状图、饼状图、折线图等,要求可以方便增加新类型的图表。

class Chart {
	private String type; //图表类型
	
	public Chart(Object[][] data, String type) {
		this.type = type;
		if (type.equalsIgnoreCase("histogram")) {
			//初始化柱状图
		}else if (type.equalsIgnoreCase("pie")) {
			//初始化饼状图
		}else if (type.equalsIgnoreCase("line")) {
			//初始化折线图
		}
	}
 
	public void display() {
		if (this.type.equalsIgnoreCase("histogram")) {
			//显示柱状图
		}else if (this.type.equalsIgnoreCase("pie")) {
			//显示饼状图
		}else if (this.type.equalsIgnoreCase("line")) {
			//显示折线图
		}	
	}
}

问题

(1) 在Chart类中包含很多“if…else…”代码块,整个类的代码冗长,阅读难度、维护难度和测试难度大,影响系统性能,程序在执行过程中需要做大量的条件判断。

(2) Chart类的职责过重,它负责初始化和显示所有的图表对象,将各种图表对象的初始化代码和显示代码集中在一个类中实现,违反了“单一职责原则”,不利于类的重用和维护;而且将大量的对象初始化代码都写在构造函数中将导致构造函数非常庞大,对象在创建时需要进行条件判断,降低了对象创建的效率。

(3) 当需要增加新类型的图表时,必须修改Chart类的源代码,违反了“开闭原则”。

(4) 客户端只能通过new关键字来直接创建Chart对象,Chart类与客户端类耦合度较高,对象的创建和使用无法分离。

(5) 客户端在创建Chart对象之前可能还需要进行大量初始化设置,例如设置柱状图的颜色、高度等,如果在Chart类的构造函数中没有提供一个默认设置,那就只能由客户端来完成初始设置,这些代码在每次创建Chart对象时都会出现,导致代码的重复。
5)案例-重构后

在这里插入图片描述

//抽象图表接口:抽象产品类
interface Chart {
	public void display();
}
 
//柱状图类:具体产品类
class HistogramChart implements Chart {
	public HistogramChart() {
		System.out.println("创建柱状图!");
	}
	
	public void display() {
		System.out.println("显示柱状图!");
	}
}
 
//饼状图类:具体产品类
class PieChart implements Chart {
	public PieChart() {
		System.out.println("创建饼状图!");
	}
	
	public void display() {
		System.out.println("显示饼状图!");
	}
}
 
//折线图类:具体产品类
class LineChart implements Chart {
	public LineChart() {
		System.out.println("创建折线图!");
	}
	
	public void display() {
		System.out.println("显示折线图!");
	}
}
 
//图表工厂类:工厂类
class ChartFactory {
    //静态工厂方法
	public static Chart getChart(String type) {
		Chart chart = null;
		if (type.equalsIgnoreCase("histogram")) {
			chart = new HistogramChart();
			System.out.println("初始化设置柱状图!");
		}
		else if (type.equalsIgnoreCase("pie")) {
			chart = new PieChart();
			System.out.println("初始化设置饼状图!");
		}
		else if (type.equalsIgnoreCase("line")) {
			chart = new LineChart();
			System.out.println("初始化设置折线图!");			
		}
		return chart;
	}
}

// 客户端
class Client {
	public static void main(String args[]) {
		Chart chart;
		chart = ChartFactory.getChart("histogram"); //通过静态工厂方法创建产品
		chart.display();
	}
}
6)案例-使用配置文件优化

将静态工厂方法的参数存储在XML或properties格式的配置文件中。

<?xml version="1.0"?>
<config>
	<chartType>histogram</chartType>
</config>

通过工具类 XMLUtil 读取配置文件中的字符串参数。

import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import java.io.*;
 
public class XMLUtil {
  //从 XML 配置文件中提取图表类型,并返回类型名
	public static String getChartType() {
		try {
			//创建文档对象
			DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = dFactory.newDocumentBuilder();
			Document doc;							
			doc = builder.parse(new File("config.xml")); 
		
			//获取包含图表类型的文本节点
			NodeList nl = doc.getElementsByTagName("chartType");
            Node classNode = nl.item(0).getFirstChild();
            String chartType = classNode.getNodeValue().trim();
            return chartType;
        }   
    catch(Exception e) {
          e.printStackTrace();
        	return null;
        }
    }
}

引入配置文件和工具类XMLUtil后,客户端修改如下:

class Client {
	public static void main(String args[]) {
		Chart chart;
		String type = XMLUtil.getChartType(); //读取配置文件中的参数
		chart = ChartFactory.getChart(type); //创建产品对象
		chart.display();
	}
}
7)总结

简单工厂模式提供了工厂类用于创建对象,将对象的创建和对象的使用分开。

1.优点

实现了对象创建和使用的分离。

引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类。

2.缺点

工厂类集中了所有产品的创建逻辑,职责过重。

系统扩展困难,添加新产品需要修改工厂逻辑。

产品类型较多时,可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。

简单工厂模式使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

3.适用场景

工厂类负责创建的对象较少。

客户端只了解传入工厂类的参数,对于如何创建对象并不关心。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

分布式游戏服务器

1、概念介绍 分布式游戏服务器是一种专门为在线游戏设计的大型系统架构。这种架构通过将游戏服务器分散部署到多台计算机&#xff08;节点&#xff09;上&#xff0c;实现了数据的分散存储和计算任务的并行处理。每个节点都负责处理一部分游戏逻辑和玩家请求&#xff0c;通过高…

TinTin Web3 Bounty 挑战杯开启,Sui 向你发出挑战邀请

以下文章来源于TinTinLand &#xff0c;作者TinTinLand。 2024 年开年最火的是什么&#xff1f; 对 Web3 来说&#xff0c;Bounty 任务应该是普通人获得行业“一杯羹”的重要捷径&#xff01; 通过深入学习各类 Web3 技术&#xff0c;凭借实战锻炼开发创新项目&#xff0c;就…

【Linux】传输层协议:TCP/UDP

目录 netstat pidof UDP协议 TCP协议 TCP协议段格式 TCP协议的相关机制 确认应答&#xff08;ACK&#xff09;机制 超时重传机制 连接管理机制 服务端状态转换 客户端状态转化 流量控制 流量控制常见问题&#xff1a; 滑动窗口 拥塞控制 延迟应答 面向字节流…

uniapp ios证书失效

前面是按照网上查找的方法 作者大大的地址 1、一个ios账户&#xff08;688付费版&#xff09; 2、登录 Apple Developer 3、创建Identifiers ps&#xff1a;创建时需继承苹果的sdk&#xff0c;只需要一个就行 点击continue再点击Register即可 4、创建.cer证书 &…

OpenAI CEO透露GPT-4表现“有点糟糕”;通义听悟音视频问答登场;Adobe整合AI功能助力3D设计创作

&#x1f989; AI新闻 &#x1f680; OpenAI CEO透露GPT-4表现“有点糟糕” 摘要&#xff1a;OpenAI的首席执行官Sam Altman在与Lex Fridman的访谈中表示&#xff0c;GPT-4的表现并不令人满意&#xff0c;认为其“有点糟糕”&#xff0c;同时对即将到来的GPT-5寄予厚望。Altm…

联想笔记本的声音键没有反应怎么办?

如果我的联想笔记本电脑上的声音按钮没有响应&#xff0c;该怎么办&#xff1f; 如果我的联想笔记本电脑上的声音按钮没有响应&#xff0c;该怎么办&#xff1f; 按下按钮后我无法控制声音。 我该怎么办&#xff1f; 以下是我为您整理的关于联想笔记本声音按键无反应的相关资料…

Power BI学习(数据可视化)

另一个也可以的工具是&#xff1a;Tableau 还有一个是&#xff1a;神策&#xff0c;主要是用于互联网的app的数据埋点 数据分析的过程&#xff1a; 数据源--数据清洗&#xff08;power query&#xff09;-构建指标 新建度量值&#xff08;power pivot&#xff09;-可视化&…

【重温设计模式】策略模式及其Java示例

策略模式的基本概念 策略模式&#xff0c;是一种常见的行为设计模式&#xff0c;主要用于处理程序中的一些相同行为&#xff0c;但具有不同实现方式的问题。在策略模式中&#xff0c;我们将每一种行为封装为一个个策略类&#xff0c;通过策略类的组合和切换&#xff0c;可以灵…

数据仓库的魅力及其在企业中的应用实践

数据仓库&#xff0c;这一创新性的概念来自于比尔恩门&#xff0c;从1980年代末提出以来&#xff0c;便凭借其独特的架构设计和强大的数据处理能力&#xff0c;在全球商业领域中掀起了一场革命。它不仅是解决企业海量数据存储和查询需求的关键技术&#xff0c;更是推动企业实现…

MYSQL数据库管理基本操作

一、数据库的基本操作 1、登录数据库 [rootmysql-server ~]#mysql -uroot -p123456 ###直接回车&#xff0c;则进入数据库[rootmysql-server ~]#mysql -u root -p ###直接回车 Enter password: ###输入密码 方法一&#xff1a…

第3关:创建零件表P,并插入数据

任务描述 零件表P由零件代码&#xff08;PNO&#xff09;、零件名(PNAME)、颜色(COLOR)、重量(WEIGHT)组成。创建零件表P(PNO,PNAME,COLOR,WEIGHT)&#xff0c;并在P表中插入下图数据。 相关知识 1、MySQL创建表的基本语法如下&#xff1a; 其中&#xff0c;table_name 是要创…

docker入门(六)—— docker镜像详细介绍,理解docker分层

docker 镜像详解 镜像本质是什么 镜像是一种轻量级、可执行的独立软件包&#xff0c;用来打包软件运行环境和基于运行环境开发的软件&#xff0c;它包含运行某个软件所需的所有内容&#xff0c;包括代码、运行时、库、环境变量和配置文件。 别人给我们生成好的一个环境&…

【黄金手指】windows操作系统环境下使用jar命令行解压和打包Springboot项目jar包

一、背景 项目中利用maven将Springboot项目打包成生产环境jar包。名为 prod_2024_1.jar。 需求是 修改配置文件中的某些参数值&#xff0c;并重新发布。 二、解压 jar -xvf .\prod_2024_1.jar释义&#xff1a; 这段命令是用于解压缩名为"prod_2024_1.jar"的Java归…

期刊如何反击一波可疑图像

出版商正在部署基于人工智能的工具来检测可疑图像&#xff0c;但生成式人工智能威胁着他们的努力。 期刊正在努力检测用于分析蛋白质和DNA的凝胶的操纵图像。图片来源&#xff1a;Shutterstock 似乎每个月都会有一系列针对研究人员的新高调指控&#xff0c;这些研究人员的论文…

软件的安装与卸载(YUM)

YUM&#xff1a;yum 是一个方便的"应用商店"&#xff0c;你可以通过它轻松地安装、更新和删除软件包&#xff0c;就像从应用商店中下载和安装应用程序一样。&#xff08;这个得用root身份&#xff0c;普通用户权限不够&#xff09; 常用命令&#xff1a; 1.安装软件…

阿里云2核4G服务器支持多少人在线?2C4G多少钱一年?

2核4G服务器支持多少人在线&#xff1f;阿里云服务器网账号下的2核4G服务器支持20人同时在线访问&#xff0c;然而应用不同、类型不同、程序效率不同实际并发数也不同&#xff0c;2核4G服务器的在线访问人数取决于多个变量因素。 阿里云2核4G服务器多少钱一年&#xff1f;2核4…

python_django网红基地孵化园场地管理系统flask

作为一个管理孵化园的网络系统&#xff0c;数据流量是非常大的&#xff0c;所以系统的设计必须满足使用方便&#xff0c;操作灵活的要求。所以在设计孵化园管理系统管理系统应达到以下目标&#xff1a; &#xff08;1&#xff09;界面要美观友好&#xff0c;检索要快捷简易&…

3.20网络编程

练习&#xff1a; 1> 创建一个工人信息库&#xff0c;包含工号&#xff08;主键&#xff09;、姓名、年龄、薪资。 2> 添加三条工人信息&#xff08;可以完整信息&#xff0c;也可以非完整信息&#xff09; 3> 修改某一个工人的薪资&#xff08;确定的一个&#xf…

应用改进SA算法实现MATLAB-HFSS交互仿真与天线优化

应用改进SA算法实现MATLAB-HFSS交互仿真与天线优化 第一章SA算法及其简单应用1.1 SA算法简介1.2 SA算法原理1.2.1 SA算法原理 1.3 Metropolis准则及退火过程中的参数控制1.3.1 Metropolis准则1.3.2退火过程中的参数控制 1.4 SA算法简单应用 第二章 改进SA算法2.1 改进方向2.2 改…

企业如何选择一个开源「好」项目?

开源 三句半 oss-roast 需求明确是关键 风险考量要周全 开源虽好不白捡 别忘合规&#xff01; 显然&#xff0c;开源已成为一股不可阻挡的洪流&#xff0c;企业拥抱开源&#xff0c;积极参与开源项目不仅是响应技术潮流的必然选择&#xff0c;更是实现自身技术创新、市场拓展等…