Java特性之设计模式【抽象工厂模式】
一、抽象工厂模式
概述
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象
抽象工厂模式提供了一种创建一系列相关或相互依赖对象的接口,而无需指定具体实现类。通过使用抽象工厂模式,可以将客户端与具体产品的创建过程解耦,使得客户端可以通过工厂接口来创建一族产品
主要解决:主要解决接口选择的问题
何时使用:我们明确地计划不同条件下创建不同实例时
优缺点
优点:
当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象
缺点:
产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码
1. 各个角色介绍
1.1抽象工厂(Abstract Factory)
声明了一组用于创建产品对象的方法,每个方法对应一种产品类型。抽象工厂可以是接口或抽象类
1.2 具体工厂(Concrete Factory)
实现了抽象工厂接口,负责创建具体产品对象的实例
1.3 抽象产品(Abstract Product)
定义了一组产品对象的共同接口或抽象类,描述了产品对象的公共方法
1.4 具体产品(Concrete Product)
实现了抽象产品接口,定义了具体产品的特定行为和属性
2. UML图
将创建 Shape 和 Color 接口和实现这些接口的实体类。下一步是创建抽象工厂类 AbstractFactory。接着定义工厂类 ShapeFactory 和 ColorFactory,这两个工厂类都是扩展了 AbstractFactory。然后创建一个工厂创造器/生成器类 FactoryProducer
AbstractFactoryPatternDemo 类使用 FactoryProducer 来获取 AbstractFactory 对象。它将向 AbstractFactory 传递形状信息 Shape(CIRCLE / RECTANGLE / SQUARE),以便获取它所需对象的类型。同时它还向 AbstractFactory 传递颜色信息 Color(RED / GREEN / BLUE),以便获取它所需对象的类型
3. 具体例子和代码
角色分配
-
Shape:形状接口
- Circle:圆形(实现形状接口)
- Rectangle:三角形(实现形状接口)
- Square:正方形(实现形状接口)
-
Color:形状接口
- Red:圆形(实现形状接口)
- Green:三角形(实现形状接口)
- Blue:正方形(实现形状接口)
-
AbstractFactory:抽象工厂
3.1 形状接口以及实现类
- Shape
package com.vinjcent.prototype.abstractFactory;/*** @author vinjcent* @description 形状接口*/
public interface Shape {/*** 绘图*/void draw();}
- Circle
package com.vinjcent.prototype.abstractFactory;/*** @author vinjcent* @description 实现形状接口-圆形*/
public class Circle implements Shape {@Overridepublic void draw() {System.out.println("Inside Circle::draw() method.");}}
- Rectangle
package com.vinjcent.prototype.abstractFactory;/*** @author vinjcent* @description 实现形状接口-长方形*/
public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Inside Rectangle::draw() method.");}}
- Square
package com.vinjcent.prototype.abstractFactory;/*** @author vinjcent* @description 实现形状接口-正方形*/
public class Square implements Shape {@Overridepublic void draw() {System.out.println("Inside Square::draw() method.");}}
3.2 颜色接口以及实现类
- Color
package com.vinjcent.prototype.abstractFactory;/*** @author vinjcent* @description 颜色接口*/
public interface Color {/*** 颜色填充*/void fill();}
- Red
package com.vinjcent.prototype.abstractFactory;/*** @author vinjcent* @description 继承颜色接口-红色*/
public class Red implements Color {@Overridepublic void fill() {System.out.println("Inside Red::fill() method.");}}
- Green
package com.vinjcent.prototype.abstractFactory;/*** @author vinjcent* @description 继承颜色接口-绿色*/
public class Green implements Color {@Overridepublic void fill() {System.out.println("Inside Green::fill() method.");}}
- Blue
package com.vinjcent.prototype.abstractFactory;/*** @author vinjcent* @description 继承颜色接口-蓝色*/
public class Blue implements Color {@Overridepublic void fill() {System.out.println("Inside Blue::fill() method.");}}
3.3 抽象工厂类以及实现类
- AbstractFactory
package com.vinjcent.prototype.abstractFactory;/*** @author vinjcent* @description 抽象工厂*/
public abstract class AbstractFactory {/*** 构造颜色实体** @param color 颜色名称* @return 颜色实体*/public abstract Color getColor(String color);/*** 构造形状实体** @param shape 形状名称* @return 形状实体*/public abstract Shape getShape(String shape);}
- ColorFactory
package com.vinjcent.prototype.abstractFactory;/*** @author vinjcent* @description 颜色工厂*/
public class ColorFactory extends AbstractFactory {@Overridepublic Shape getShape(String shapeType) {return null;}@Overridepublic Color getColor(String color) {if (color == null) {return null;}if (color.equalsIgnoreCase("RED")) {return new Red();} else if (color.equalsIgnoreCase("GREEN")) {return new Green();} else if (color.equalsIgnoreCase("BLUE")) {return new Blue();}return null;}
}
- ShapeFacotry
package com.vinjcent.prototype.abstractFactory;/*** @author vinjcent* @description 形状工厂*/
public class ShapeFactory extends AbstractFactory {@Overridepublic Shape getShape(String shapeType) {if (shapeType == null) {return null;}// (优化:这里可以通过反射来获取)if (shapeType.equalsIgnoreCase("CIRCLE")) {return new Circle();} else if (shapeType.equalsIgnoreCase("RECTANGLE")) {return new Rectangle();} else if (shapeType.equalsIgnoreCase("SQUARE")) {return new Square();}return null;}@Overridepublic Color getColor(String color) {return null;}
}
3.4 工厂生产者
- FactoryProducer
package com.vinjcent.prototype.abstractFactory;/*** @author vinjcent* @description 工厂生产者*/
public class FactoryProducer {/*** 根据选择获取对应的生产工厂** @param choice 选择类型* @return 具体的工厂*/public static AbstractFactory getFactory(String choice) {if (choice.equalsIgnoreCase("SHAPE")) {return new ShapeFactory();} else if (choice.equalsIgnoreCase("COLOR")) {return new ColorFactory();}return null;}
}
3.5 测试主函数
package com.vinjcent.prototype.abstractFactory;/*** @author vinjcent*/
public class Main {public static void main(String[] args) {// 1.获取形状工厂AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");// 2.获取形状为 Circle 的对象Shape circle = shapeFactory.getShape("CIRCLE");// 2.1 调用 Circle 的 draw 方法circle.draw();// 3.获取形状为 Rectangle 的对象Shape rectangle = shapeFactory.getShape("RECTANGLE");// 3.1 调用 Rectangle 的 draw 方法rectangle.draw();// 4.获取形状为 Square 的对象Shape square = shapeFactory.getShape("SQUARE");// 4.1 调用 Square 的 draw 方法square.draw();// 5.获取颜色工厂AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");// 6.获取颜色为 Red 的对象Color red = colorFactory.getColor("RED");// 6.1 调用 Red 的 fill 方法red.fill();// 7.获取颜色为 Green 的对象Color green = colorFactory.getColor("GREEN");// 7.1调用 Green 的 fill 方法green.fill();// 8.获取颜色为 Blue 的对象Color blue = colorFactory.getColor("BLUE");// 8.1调用 Blue 的 fill 方法blue.fill();}
}
- 测试结果
4. 使用场景
- QQ 换皮肤,一整套一起换
- 生成不同操作系统的程序
注意事项:
产品族难扩展,产品等级易扩展
相关文章:
Java特性之设计模式【抽象工厂模式】
一、抽象工厂模式 概述 抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式 在抽象工厂模式中,接口是…...
机器学习简介
引言 为何现在机器学习如此热门? 主要原因是由于“人类无论如何也做不到在短时间内实现从大量的数据中自动的计算出正确的结果操作”。 什么是机器学习? 所谓的机器学习,就是通过对数据进行反复的学习,来找出其中潜藏的规律和模式…...
linux之perf(2)list事件
Linux之perf(2)list事件 Author:Onceday Date:2023年9月3日 漫漫长路,才刚刚开始… 参考文档: Tutorial - Perf Wiki (kernel.org)perf-list(1) - Linux manual page (man7.org) 1. 概述 perf list用于列出可用的性能事件,这…...
将多个EXCEL 合并一个EXCEL多个sheet
合并老版本xls using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using NPOI.HSSF.UserModel; …...
【送书活动】揭秘分布式文件系统大规模元数据管理机制——以Alluxio文件系统为例
前言 「作者主页」:雪碧有白泡泡 「个人网站」:雪碧的个人网站 「推荐专栏」: ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄,vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄ÿ…...
微信小程序——数据绑定
在微信小程序中,可以通过以下代码实现数据绑定: 在WXML中,使用双大括号{{}}绑定数据,将数据渲染到对应的视图中。 <view>{{message}}</view>在JS中,定义一个数据对象,并将其绑定到页面的data…...
libbpf-bootstrap安卓aarch64适配交叉编译
1.为什么移植 疑惑 起初我也认为,像libbpf-bootstrap这样在ebpf程序开发中很常用的框架,理应支持不同架构的交叉编译。尤其是向内核态的ebpf程序本身就是直接通过clang的-target btf直接生成字节码,各个内核上的ebpf虚拟机大同小异…...
【剑指Offer】24.反转链表
题目 定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL限制: 0 < 节点个数 < 5000 解答 源代码 /*** Defin…...
04-docker compose容器编排
Docker Compose简介 Docker Compose是什么 Compose 是Docker公司推出的一个工具软件,可以管理多个Dokcer容器组成一个应用。你需要定义一个YAML格式的配置文件 docker-compose.yml,写好多个容器之间的调用关系。然后,只要一个命令&#…...
通过位运算打多个标记
通过位运算打多个标记 如何在一个字段上,记录多个标记? 如何在一个字段上,记录不同类型的多个标记? 如何用较少的字段,记录多个标记? 如何在不增加字段的要求下,记录新增的标记? 在实…...
[学习笔记]Node2Vec图神经网络论文精读
参考资料:https://www.bilibili.com/video/BV1BS4y1E7tf/?p12&spm_id_frompageDriver Node2vec简述 DeepWalk的缺点 用完全随机游走,训练节点嵌入向量,仅能反应相邻节点的社群相似信息,无法反映节点的功能角色相似信息。 …...
C# Linq源码分析之Take(五)
概要 本文在C# Linq源码分析之Take(四)的基础上继续从源码角度分析Take的优化方法,主要分析Where.Select.Take的使用案例。 Where.Select.Take的案例分析 该场景模拟我们显示中将EF中与数据库关联的对象进行过滤,然后转换成Web…...
性能监控-grafana+prometheus+node_exporter
Prometheus是一个开源的系统监控和报警工具。它由SoundCloud开发并于2012年发布,后来成为了一个独立的开源项目,并得到了广泛的应用和支持。 Prometheus的主要功能包括采集和存储各种系统和应用程序的监控数据,并提供强大的查询语言PromQL来…...
(STM32H5系列)STM32H573RIT6、STM32H573RIV6、STM32H573ZIT6嵌入式微控制器基于Cortex®-M33内核
一、应用 工业(PLC、工业电机控制、泵和压缩机) 智能家居(空调、冰箱、冰柜、中央警报系统、洗衣机) 个人电子产品(键盘、智能手机、物联网标签、跟踪设备) 智能城市(工业通信、照明控制、数字…...
mysql配置bind-address不生效
1、前言 因为要ip直接访问mysql,故去修改bind-address参数,按照mysql配置文件查找顺序是:/etc/my.cnf、/etc/mysql/my.cnf、~/.my.cnf,服务器上没有 /etc/my.cnf文件,故去修改 /etc/mysql/my.cnf文件,但是一…...
Linux相关指令(下)
cat指令 查看目标文件的内容 常用选项: -b 对非空输出行编号 -n 对输出的所有行编号 -s 不输出多行空行 一个重要思想:linux下一切皆文件,如显示器文件,键盘文件 cat默认从键盘中读取数据再打印 退出可以ctrlc 输入重定向<…...
Codeforces Round 855 (Div 3)(A - F)
Codeforces Round 855 (Div. 3)(A - F) Codeforces Round 855 (Div. 3) A. Is It a Cat?(思维) 思路:先把所有字母变成小写方便判断 , 然后把每一部分取一个字母出来 , 判断和‘meow’是否相同即可。 复杂度 O ( n…...
Friend.tech(FT):社交媒体金融的未来,真的如此美好吗?
Friend.tech(FT)是一个在2023年8月10日正式推出的社交金融平台,它的特点在于允许用户购买和出售创作者的股票(shares),这些股票赋予用户访问创作者内容的权利。FT的推出引发了广泛的关注,吸引了…...
yolov7中Concat之后加注意力模块(最复杂的情况)
1、common.py中找到Concat模块,复制一份 2、要传参进来,dim通道数 3、然后找yolo.py模块,添加 4、yaml里替换 5、和加的位置也有关系...
解除百度安全验证
使用chrome浏览器用百度浏览时,一直弹百度安全验证: 在设置里进行重置: 然后重启浏览器就可以了。...
Codeforces Round 731 (Div 3)(A - F)
Codeforces Round 731 (Div. 3)(A - F) Dashboard - Codeforces Round 731 (Div. 3) - Codeforces A. Shortest Path with Obstacle(思维) 思路:显然要计算 A → B 之间的曼哈顿距离 , 要绕开 F 当且仅当 AB形成的直线平行于坐…...
Python的sort()与sorted()函数详解
目录 sort()函数 sorted()函数 key参数 区别 sort()函数 sort()方法:该方法用于原地对列表进行排序,即直接在原始列表上进行排序操作,并不返回一个新的列表。 my_l…...
用python实现基本数据结构【04/4】
说明 如果需要用到这些知识却没有掌握,则会让人感到沮丧,也可能导致面试被拒。无论是花几天时间“突击”,还是利用零碎的时间持续学习,在数据结构上下点功夫都是值得的。那么Python 中有哪些数据结构呢?列表、字典、集…...
“必抓!”算法
一个程序员一生中可能会邂逅各种各样的算法,但总有那么几种,是作为一个程序员一定会遇见且大概率需要掌握的算法。今天就来聊聊这些十分重要的“必抓!”算法吧~ 你可以从以下几个方面进行创作(仅供参考) 一ÿ…...
【监控系统】Promethus整合Alertmanager监控告警邮件通知
【监控系统】Promethus整合Alertmanager监控告警邮件通知 Alertmanager是一种开源软件,用于管理和报警监视警报。它与Prometheus紧密集成,后者是一种流行的开源监视和警报系统。Alertmanager从多个源接收警报和通知,并根据一组配置规则来决定…...
【韩顺平】Linux基础
目录 1.网络连接三种方式 1.1 桥接模式:虚拟系统可以和外部系统通讯,但是容易造成IP冲突【1-225】 1.2 NAT模式:网络地址转换模式。虚拟系统可以和外部系统通讯,不造成IP冲突。 1.3 主机模式:独立的系统。 2.虚拟机…...
好奇一下各个大模型对华为mate60系列的看法
目前华为Mate60系列手机已上市并获抢购,个人觉得很不错,很好奇各个AI大模型对此事的看法,于是对chatGPT、文心一言、讯飞星火进行了一下粗浅的测试。 题目一(看看三个模型的综合分析能力) “目前华为Mate60系列手机已…...
UMA 2 - Unity Multipurpose Avatar☀️五.如何使用别人的Recipe和创建自己的服饰Recipe
文章目录 🟥 使用别人的Recipe1️⃣ 导入UMA资源效果展示2️⃣ 更新Library3️⃣ 试一下吧🟧 创建自己的服饰Recipe1️⃣ 创建自己的服饰Recipe2️⃣ 选择应用到的Base Recipe3️⃣ 指定显示名 / 佩戴位置 / 隐藏部位4️⃣ 给该服饰Recipe指定Slot / Overlay🚩 赋予Slot�…...
代码随想录训练营第五十六天| 583. 两个字符串的删除操作 、72. 编辑距离
583. 两个字符串的删除操作 题目链接/文章讲解/视频讲解:代码随想录 1.代码展示 //583.两个字符串的删除操作 int minDistance(string word1, string word2) {//step1 构建dp数组,dp[i][j]的含义是要使以i-1为结尾的word1和以j-1为结尾的word2//删除其元…...
hive解决了什么问题
hive出现的原因 Hive 出现的原因主要有以下几个: 传统数据仓库无法处理大规模数据:传统的数据仓库通常采用关系型数据库作为底层存储,这种数据库在处理大规模数据时效率较低。MapReduce 难以使用:MapReduce 是一种分布式计算框架…...
wordpress 免费 主题下载/宁波网站推广运营公司
springboot实现企业微信机器人自动按时播报天气 第一步搭建项目。。。这个没有什么好说的 配置: <dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.5</version&…...
网站关于我们什么意思/小程序生成平台系统
题目: 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那…...
网站开发时数据库的工作/搜索引擎seo外包
前面两篇文章,分别介绍了使用递归和非递归算法加载树形结构数据的方式,本篇文章,则是自己闲下来的时候,进行的一点小思考。 一、什么地方会用到树形结构 刚开始一看到这种结构的时候,最先是想到了家谱。家谱就是一种树…...
wordpress数据字典/百度seo公司一路火
UIApplicationDelegate 是最常见的 协议之一 这个协议声明了继承于单例模式下UIApplication对象的委托方法。这些方法提供了有关在应用程序执行时或发生重要变化时 进行响应的机会。比如(在应用程序执行时,完成启动时,内存低时……ÿ…...
电商网站的制作流程/大学生网络营销策划方案书
在angular中,整个应用就是一个组件树,用户看到的页面就是由几个被激活的组件组成的,用户可以通过一些操作从一个组件路由到另一个组件,当用户从一个组件路由到另一个组件时用户看到的页面就会发生一些变化,因为用户激活…...
中小型网站建设与管理总结/怎么在广告联盟接广告
初级的程序员或经验不足的程序员往往只意识到自己的程序是写给计算机的,而不会在意程序其实也是写给人的,或在意得不够、不全面。 写给机器的程序,往往追求的是运行正确、执行效率能满足要求。但程序员的任务仅仅就是把业务逻辑转成机器能编译…...