设计模式之抽象工厂模式解析

news2024/12/23 5:30:44
抽象工厂模式
1)问题

工厂方法模式中的每个工厂只生产一类产品,会导致系统中存在大量的工厂类,增加系统的开销。

2)概述
a)产品族 和 产品等级结构

产品等级结构:产品的继承结构;

产品族:由同一个工厂生产,位于不同产品等级结构中的一组产品;

在这里插入图片描述

b)适用场景

当系统所提供的工厂,生产的是多个位于不同产品等级结构、属于不同类型的具体产品时,可以使用抽象工厂模式。

工厂方法模式针对的是一个产品等级结构,而抽象工厂模式需要面对多个产品等级结构。

在这里插入图片描述

每个具体工厂可以生产属于一个产品族的所有产品,例如生产颜色相同的正方形、圆形和椭圆形,所生产的产品又位于不同的产品等级结构中。

如果使用工厂方法模式,需要提供15个具体工厂,而使用抽象工厂模式只需要提供5个具体工厂,极大减少了系统中类的个数。

c)定义

提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类;

在抽象工厂模式中,每一个具体工厂都提供了多个工厂方法用于产生多种不同类型的产品,这些产品构成了一个产品族;

在这里插入图片描述

3)角色

AbstractFactory(抽象工厂):声明了一组用于创建一族产品的方法,每一个方法对应一种产品。

ConcreteFactory(具体工厂):实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。

AbstractProduct(抽象产品):为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。

ConcreteProduct(具体产品):定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。

abstract class AbstractFactory {
	public abstract AbstractProductA createProductA(); //工厂方法一
	public abstract AbstractProductB createProductB(); //工厂方法二
	……
}

class ConcreteFactory1 extends AbstractFactory {
	//工厂方法一
	public AbstractProductA createProductA() {
    	return new ConcreteProductA1();
	}
	//工厂方法二
	public AbstractProductB createProductB() {
    	return new ConcreteProductB1();
	}
	……
}

与工厂方法模式一样,抽象工厂模式也可为每一种产品提供一组重载的工厂方法,以不同的方式对产品对象进行创建。

4)案例-初始方案

在这里插入图片描述

问题

增加新皮肤时,需要增加大量类,每个新增具体组件都需要增加一个具体工厂,类的个数成对增加,影响系统维护成本和运行开销;

每个组件都需要一个具体工厂,在使用时要逐个设置,在客户端代码和配置文件都较为复杂。

5)案例-重构后

在这里插入图片描述

//按钮接口:抽象产品
interface Button {
	public void display();
}
 
//Spring按钮类:具体产品
class SpringButton implements Button {
	public void display() {
		System.out.println("显示浅绿色按钮。");
	}
}
 
//Summer按钮类:具体产品
class SummerButton implements Button {
	public void display() {
		System.out.println("显示浅蓝色按钮。");
	}	
}
 
//文本框接口:抽象产品
interface TextField {
	public void display();
}
 
//Spring文本框类:具体产品
class SpringTextField implements TextField {
	public void display() {
		System.out.println("显示绿色边框文本框。");
	}
}
 
//Summer文本框类:具体产品
class SummerTextField implements TextField {
	public void display() {
		System.out.println("显示蓝色边框文本框。");
	}	
}
 
//组合框接口:抽象产品
interface ComboBox {
	public void display();
}
 
//Spring组合框类:具体产品
class SpringComboBox implements ComboBox {
	public void display() {
		System.out.println("显示绿色边框组合框。");
	}
}
 
//Summer组合框类:具体产品
class SummerComboBox implements ComboBox {
	public void display() {
		System.out.println("显示蓝色边框组合框。");
	}	
}
 
//界面皮肤工厂接口:抽象工厂
interface SkinFactory {
	public Button createButton();
	public TextField createTextField();
	public ComboBox createComboBox();
}
 
//Spring皮肤工厂:具体工厂
class SpringSkinFactory implements SkinFactory {
	public Button createButton() {
		return new SpringButton();
	}
 
	public TextField createTextField() {
		return new SpringTextField();
	}
 
	public ComboBox createComboBox() {
		return new SpringComboBox();
	}
}
 
//Summer皮肤工厂:具体工厂
class SummerSkinFactory implements SkinFactory {
	public Button createButton() {
		return new SummerButton();
	}
 
	public TextField createTextField() {
		return new SummerTextField();
	}
 
	public ComboBox createComboBox() {
		return new SummerComboBox();
	}
}

配置文件 config.xml 中存储了具体工厂类的类名

<?xml version="1.0"?>
<config>
	<className>SpringSkinFactory</className>
</config>

客户端代码

class Client {
	public static void main(String args[]) {
    //使用抽象层定义
		SkinFactory factory;
		Button bt;
		TextField tf;
		ComboBox cb;
		
		factory = (SkinFactory)XMLUtil.getBean();
		bt = factory.createButton();
		tf = factory.createTextField();
		cb = factory.createComboBox();
		
		bt.display();
		tf.display();
		cb.display();
	}
}

如果需要增加新的皮肤,只需增加一族新的具体组件并提供一个新的具体工厂,修改配置文件即可使用新的皮肤,原有代码无须修改

6)开闭原则的倾斜性

在抽象工厂模式中,增加新的产品族很方便,但是增加新的产品等级结构很麻烦。

增加产品族:只需要增加具体产品并对应增加一个新的具体工厂,对已有代码无须做任何修改。

增加新的产品等级结构:需要修改所有的工厂角色,包括抽象工厂类,在所有的工厂类中都需要增加生产新产品的方法。

7)总结

1.优点

增加新的产品族很方便,无须修改已有系统。

2.缺点

增加新的产品等级结构需要对原有系统进行较大修改,需要修改抽象层代码。

3.适用场景

用户无须关心对象的创建过程,将对象的创建和使用解耦。

系统中有多于一个的产品族,而每次只使用其中某一产品族。

属于同一个产品族的产品将在一起使用。

产品等级结构稳定,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构。

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

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

相关文章

TnT-LLM: Text Mining at Scale with Large Language Models

TnT-LLM: Text Mining at Scale with Large Language Models 相关链接&#xff1a;arxiv 关键字&#xff1a;Large Language Models (LLMs)、Text Mining、Label Taxonomy、Text Classification、Prompt-based Interface 摘要 文本挖掘是将非结构化文本转换为结构化和有意义的…

Java开发---上海得帆(一面)

面试感受 这是我的第一次面试&#xff0c;我感觉我这次面试的很差&#xff0c;很糟糕&#xff0c;十分的糟糕&#xff0c;万分的糟糕。第一次面试&#xff0c;面试了半个小时。我去真的好紧张&#xff0c;脑子里一篇空白。脑子空白还不是最惨的&#xff0c;最惨的是那个八股文…

使用Lerna搭建业务组件库

Lerna基本概念 Lerna 是一个用来优化托管在 git\npm 上的多 package 代码库的工作流的一个管理工具,可以让你在主项目下管理多个子项目&#xff0c;从而解决了多个包互相依赖&#xff0c;且发布时需要手动维护多个包的问题。 主要功能&#xff1a; 为单个包或多个包运行命令 …

【GPT概念-03】:人工智能中的注意力机制

说明 注意力机制生成分数&#xff08;通常使用输入函数&#xff09;&#xff0c;确定对每个数据部分的关注程度。这些分数用于创建输入的加权总和&#xff0c;该总和馈送到下一个网络层。这允许模型捕获数据中的上下文和关系&#xff0c;而传统的固定序列处理方法可能会遗漏这…

JVM垃圾收集器你会选择吗?

目录 一、Serial收集器 二、ParNew收集器 三、Paralle Scavenge 四、Serial Old 五、Parallel Old 六、CMS收集器 6.1 CMS对处理器资源非常敏感 6.2 CMS容易出现浮动垃圾 6.3 产生内存碎片 七、G1 收集器 八、如何选择合适的垃圾收集器 JVM 垃圾收集器是Java虚…

走迷宫---dfs在矩阵图里的应用模板

题目描述如下&#xff1a; dfs算法解决迷宫问题的一个标准模板 &#xff0c;通过递归与回溯暴力遍历所有能走的点&#xff0c;并比较找出所有可行方案的最优解 解决这道问题的核心思想和组合数如出一辙&#xff0c;可以说是组合数的升级版 结合注释看dfs更清晰易懂&#xff0…

群晖HomeAssistant安装HACS插件商店结合内网穿透实现公网访问本地智能家居

文章目录 基本条件一、下载HACS源码二、添加HACS集成三、绑定米家设备 ​ 上文介绍了如何实现群晖Docker部署HomeAssistant&#xff0c;通过内网穿透在户外控制家庭中枢。本文将介绍如何安装HACS插件商店&#xff0c;将米家&#xff0c;果家设备接入 Home Assistant。 基本条件…

微博修改密码后无法通过微博开放接口发送微博

生产环境&#xff0c;因密码修改导致授权失效致接口发送微博失效&#xff01;内部网站编辑完博文后无法发送微博。在修改密码时&#xff0c;有提示授权应用失效&#xff0c;操作人员不清晰情况&#xff0c;直接忽视。 微博应用开放接口----》微博转发博文接口文档 无示例 遗憾…

LabVIEW提升舱救援通讯监测系统

LabVIEW提升舱救援通讯监测系统 随着科技的进步&#xff0c;煤矿救援工作面临着许多新的挑战。为了提高救援效率和安全性&#xff0c;设计并实现了一套基于LabVIEW的提升舱救援通讯监测系统。该系统能够实时监控提升舱内的环境参数和视频图像&#xff0c;确保救援人员和被困人…

AI程序员诞生:对程序员的影响与未来展望

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;日常聊聊 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 方向一&#xff1a;AI程序员的优势分析 方向二&#xff1a;AI程序员局限性 方向三&#xff1a;对程序员职业的影响 方向四&…

会员项目定价卡css3特效

会员项目定价卡css3特效&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面 下载地址 会员项目定价卡css3特效代码

2024年了,还能学自动化吗?

大家都说2024年软件测试行业会卷的更厉害&#xff0c;简单的功能测试不再是入门的标准&#xff0c;那么2024年是否可以从自动化测试这块冲一把呢&#xff1f; 我们先来看看过去的一年自动化测试在测试行业中的发展分析&#xff1a; 01 市场需求增长 随着技术的进步和企业对软件…

流畅的 Python 第二版(GPT 重译)(十一)

第二十章&#xff1a;并发执行器 抨击线程的人通常是系统程序员&#xff0c;他们心中有着典型应用程序员终其一生都不会遇到的用例。[…] 在 99%的用例中&#xff0c;应用程序员可能会遇到的情况是&#xff0c;生成一堆独立线程并将结果收集到队列中的简单模式就是他们需要了解…

SpringBoot-03 | SpringBoot自动配置

SpringBoot-03 | SpringBoot自动配置 原理分析代码示例源码剖析SpringBootConfiguration&#xff1a;组合注解&#xff0c;标记当前类为配置类ComponentScanEnableAutoConfigurationImport加载spring.factoriesrun初始化加载spring.factoriesspring.factories中的钩子类 网上盗…

流畅的 Python 第二版(GPT 重译)(八)

第十五章&#xff1a;关于类型提示的更多内容 我学到了一个痛苦的教训&#xff0c;对于小程序来说&#xff0c;动态类型很棒。对于大型程序&#xff0c;你需要更加纪律严明的方法。如果语言给予你这种纪律&#xff0c;而不是告诉你“嗯&#xff0c;你可以做任何你想做的事情”&…

HTML中的常用标签用法总结

&#x1f31f; 欢迎来到 我的博客&#xff01; &#x1f308; &#x1f4a1; 探索未知, 分享知识 !&#x1f4ab; 本文目录 1. 标题标签2. 段落标签3. 链接标签4. 列表标签5. 图像标签6. 表格标签 1. 标题标签 <h1>至<h6>用于定义标题。<h1>是最大的标题&am…

【GameFramework框架内置模块】13、流程(Procedure)

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址QQ群&#xff1a;398291828 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 【GameFramework框架】系列教程目录&#xff1a;…

学点Java_Day6_基于Copyright和Actions On Save的IDEA自动更新文件最后编辑时间的方法研究(IDEA2021.2及以上)

0 版本要求 IDEA2021.2及以上&#xff0c;我用的IntelliJ IDEA 2023.2.4 1 操作 1.1 Copyright设置 ① CtrlAltS打开设置&#xff08;Settings&#xff09;→ Editor → Copyright   ② Copyright → Copyright Profiles → → 取名 → OK   ③ 复制下面内容到框里&am…

【数据结构】顺序表和链表详解顺序表和链表的实现

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;数据结构_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.线性表 1.1 顺序表 1.1.1 概念及结构 1.1.2 静态顺序表 1.1.3 动态顺序表 1.2 链表 1.2.1 链表的概念及结构 1.2.2 链表…

上海王梓标准件制造有限公司隆重参加上海紧固件专业展

随着全球工业制造业的高速发展&#xff0c;标准件行业做为基础部件的供应链环节越来越受到重视。标准件&#xff0c;这类微不足道的小零件&#xff0c;在维护工业世界的稳定和发展中是至关重要的。在这样一个紧要关头&#xff0c;上海王梓标准件制造有限公司&#xff08;下称“…