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

news2024/11/27 2:46:16
简单工厂模式

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

低阶:简单工厂模式;

高阶:抽象工厂模式;

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.适用场景

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

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

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

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

相关文章

设备安全与设备管理系统的融合发展之路

随着企业运营的不断复杂化和市场竞争的加剧&#xff0c;设备安全与设备管理系统的融合发展已经成为企业追求卓越运营、实现持续发展的必经之路。这种融合不仅提升了设备的安全性&#xff0c;更提高了设备管理的效率与精准度&#xff0c;为企业的整体运营奠定了坚实基础。 一、设…

华为机试真题练习汇总(81~90)

华为机试真题练习汇总&#xff08;81~90&#xff09; 华为机试真题练习汇总&#xff08;81~90&#xff09;HJ81 字符串字符匹配** HJ82 将真分数分解为埃及分数HJ83 二维数组操作HJ84 统计大写字母个数HJ85 最长回文子串HJ86 求最大连续bit数HJ87 密码强度等级* HJ88 扑克牌大小…

Go语言实战:深入掌握标准库flag的强大用法

Go语言实战&#xff1a;深入掌握标准库flag的强大用法 引言flag库基础命令行参数的基本概念使用flag库定义和解析命令行参数处理非选项命令行参数小结 高级用法自定义Flag的解析命令行参数的分组和嵌套小结 实战技巧组织复杂命令行应用的参数错误处理和用户帮助信息调试命令行应…

PHP 服务实现监控可观测性最佳实践

前言 本次实践主要是介绍 PHP 服务通过无侵入的方式接入观测云进行全面的可观测。 环境信息 主机环境&#xff1a;CentOS 7.8PHP&#xff1a;7.4.33MySQL&#xff1a;5.7 接入方案 准备工作 安装 DataKit # 需要把token 改成观测云空间的实际token值&#xff08;可在观测…

G*T、文心一言微信 AI 机器人的时代已经来临!

前言 在当今的科技时代&#xff0c;人工智能&#xff08;AI&#xff09;的发展速度可谓是日新月异。其中&#xff0c;自然语言处理&#xff08;NLP&#xff09;领域的模型&#xff0c;如 G*T、文心一言等&#xff0c;已经成为了 AI 领域的主流。不仅如此&#xff0c;将 AI 接入…

铸铁平台制造工艺有多精细你知道吗——河北北重

铸铁平台的制造工艺要求相对较高&#xff0c;需要经过以下精细工艺&#xff1a; 材料选择&#xff1a;铸铁平台通常使用灰口铸铁&#xff0c;其具有良好的耐磨性和强度。材料的选择要考虑到使用环境和平台的功能需求。 模具制造&#xff1a;根据设计要求制作模具&#xff0c;模…

算法---二分查找练习-3(山脉数组的顶峰索引)

山脉数组的顶峰索引 1. 题目解析2. 讲解算法原理3. 编写代码 1. 题目解析 题目地址&#xff1a;点这里 2. 讲解算法原理 初始化两个指针 left 和 right&#xff0c;分别指向数组的起始位置和结束位置。 进入循环&#xff0c;循环条件为 left < right。 在每次循环中&…

全平台(淘宝1688京东)商品详情API接口(item_get-获得全平台商品详情接口)

全平台商品详情API接口&#xff08;item_get-获得全平台商品详情接口&#xff09;&#xff0c;全平台API接口可获取到商品链接&#xff0c;商品ID&#xff0c;商品标题&#xff0c;商品价格&#xff0c;品牌名称&#xff0c;店铺昵称&#xff0c;sku规格&#xff0c;sku属性&am…

自注意力机制的理解

一、自注意力要解决什么问题 循环神经网络由于信息传递的容量以及梯度消失问题&#xff0c;只能建立短距离依赖关系。为了建立长距离的依赖关系&#xff0c;可以增加网络的层数或者使用全连接网络。但是全连接网络无法处理变长的输入序列&#xff0c;另外&#xff0c;不同的输…

【Android】【Bluetooth Stack】蓝牙电话本协议之同步通讯录分析(超详细)

1. 精讲蓝牙协议栈&#xff08;Bluetooth Stack&#xff09;&#xff1a;SPP/A2DP/AVRCP/HFP/PBAP/IAP2/HID/MAP/OPP/PAN/GATTC/GATTS/HOGP等协议理论 2. 欢迎大家关注和订阅&#xff0c;【蓝牙协议栈】专栏会持续更新中.....敬请期待&#xff01; 目录 1. 协议简述 1.1 PBAP…

【十二】【算法分析与设计】滑动窗口(3)

30. 串联所有单词的子串 给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。 s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。 例如&#xff0c;如果 words ["ab","cd","ef"]&#xff…

【Godot4.2】 基于SurfaceTool的3D网格生成与体素网格探索

概述 说明&#xff1a;本文基础内容写于2023年6月&#xff0c;由三五篇文章汇总而成&#xff0c;因为当时写的比较潦草&#xff0c;过去时间也比较久了&#xff0c;我自己都得重新阅读和理解一番&#xff0c;才能知道自己说了什么&#xff0c;才有可能重新优化整理。 因为我对…

使用WordPress在US Domain Center上建立摄影网站的详细教程

第一部分&#xff1a;介绍摄影网站 摄影网站是摄影师展示作品、分享经验、提供服务的在线平台。在摄影网站上&#xff0c;摄影师可以展示自己的摄影作品、发布摄影日志、接受客户预约等。使用WordPress搭建摄影网站具有灵活性和可扩展性&#xff0c;可以通过选择适合的主题和插…

视频转文字怎么转?这几个转换方法收藏一下

视频转文字怎么转&#xff1f;在信息爆炸的时代&#xff0c;视频内容日益丰富&#xff0c;但如何快速、准确地提取视频中的关键信息却成为了一个挑战。本文将为你详细介绍视频转文字的方法&#xff0c;让你轻松提取视频内容&#xff0c;提高信息获取效率。 方法一&#xff1a;清…

【赠书第21期】游戏力:竞技游戏设计实战教程

文章目录 前言 1 竞技游戏设计的核心要素 1.1 游戏机制 1.2 角色与技能 1.3 地图与环境 2 竞技游戏设计的策略与方法 2.1 以玩家为中心 2.2 不断迭代与优化 2.3 营造竞技氛围与社区文化 3 实战案例分析 4 结语 5 推荐图书 6 粉丝福利 前言 在数字化时代的浪潮中&…

IO多分复用

#include<myhead.h> #define SER_PORT 8888 //服务器端口号 #define SER_IP "192.168.65.131" //服务器IPint main(int argc, const char *argv[]) {//1、创建一个套接字int sfd -1;sfd socket(AF_INET, SOCK_STREAM, 0); //参数1&#xff1a;…

win10共享了连接打印机报错提示0000011B

在Windows 10系统中&#xff0c;当用户尝试连接共享打印机时遇到错误代码0x0000011B&#xff0c;通常表示存在与打印机驱动程序或系统更新相关的兼容性问题。以下是针对这个问题的一些解决方案&#xff1a; 卸载特定系统更新&#xff1a; 根据多个来源的信息&#xff0c;错误0x…

软考考哪个好?软考中级到高级方向该如何计划

刚接触软考的朋友可能对软考的科目选择比较迷茫&#xff0c;不知道自己该怎么选方向&#xff0c;怎么选级别&#xff0c;这属于再正常不过的事情了&#xff0c;毕竟谁看到这些都可能有些迷茫&#xff0c;要理清自己的选择还是要从自身的几个方面开始的。 软考的考试专业类别就…

vue2从基础到高级学习笔记

在实际的工作中,我常使用vue的用法去实现效果,但是你要是问我为什么这样写,它的原理是啥就答不上来了。对vue的认知一直停留在表面,写这篇文章主要是为了理清并弄透彻vue的原理。 学习目标 1 学会一些基本用法的原理 2 弄懂vue核心设计原理 3 掌握vue高级api的用法 一 vue…

【前端寻宝之路】学习和总结HTML的标签属性

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法|MySQL| ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不…