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浏览器用百度浏览时,一直弹百度安全验证: 在设置里进行重置: 然后重启浏览器就可以了。...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
VSCode 使用CMake 构建 Qt 5 窗口程序
首先,目录结构如下图: 运行效果: cmake -B build cmake --build build 运行: windeployqt.exe F:\testQt5\build\Debug\app.exe main.cpp #include "mainwindow.h"#include <QAppli...
「Java基本语法」变量的使用
变量定义 变量是程序中存储数据的容器,用于保存可变的数据值。在Java中,变量必须先声明后使用,声明时需指定变量的数据类型和变量名。 语法 数据类型 变量名 [ 初始值]; 示例:声明与初始化 public class VariableDemo {publi…...
以太网PHY布局布线指南
1. 简介 对于以太网布局布线遵循以下准则很重要,因为这将有助于减少信号发射,最大程度地减少噪声,确保器件作用,最大程度地减少泄漏并提高信号质量。 2. PHY设计准则 2.1 DRC错误检查 首先检查DRC规则是否设置正确,然…...
篇章一 论坛系统——前置知识
目录 1.软件开发 1.1 软件的生命周期 1.2 面向对象 1.3 CS、BS架构 1.CS架构编辑 2.BS架构 1.4 软件需求 1.需求分类 2.需求获取 1.5 需求分析 1. 工作内容 1.6 面向对象分析 1.OOA的任务 2.统一建模语言UML 3. 用例模型 3.1 用例图的元素 3.2 建立用例模型 …...
VASP软件在第一性原理计算中的应用-测试GO
VASP软件在第一性原理计算中的应用 VASP是由维也纳大学Hafner小组开发的一款功能强大的第一性原理计算软件,广泛应用于材料科学、凝聚态物理、化学和纳米技术等领域。 VASP的核心功能与应用 1. 电子结构计算 VASP最突出的功能是进行高精度的电子结构计算ÿ…...
