2022-15-Java 设计模式-抽象工厂模式

2023-11-07

在工厂方法模式中,我们使用一个工厂创建一个产品,一个具体工厂对应一个具体产品,但有时候我们需要一个工厂能够提供多个产品对象,而不是单一的对象,这个时候我们就需要使用抽象工厂模式。

    在介绍抽象工厂模式前,我们先厘清两个概念:

产品等级结构:产品等级结构指的是产品的继承结构,例如一个空调抽象类,它有海尔空调、格力空调、美的空调等一系列的子类,那么这个空调抽象类和他的子类就构成了一个产品等级结构。
产品族:产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。比如,海尔工厂生产海尔空调、海尔冰箱,那么海尔空调则位于空调产品族中。
1、什么是抽象工厂模式:

    抽象工厂模式主要用于创建相关对象的家族。当一个产品族中需要被设计在一起工作时,通过抽象工厂模式,能够保证客户端始终只使用同一个产品族中的对象;并且通过隔离具体类的生成,使得客户端不需要明确指定具体生成类;所有的具体工厂都实现了抽象工厂中定义的公共接口,因此只需要改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。

    但该模式的缺点在于添加新的行为时比较麻烦,如果需要添加一个新产品族对象时,需要更改接口及其下所有子类,这必然会带来很大的麻烦。

2、UML结构图:

抽象工厂 AbstractFactory:定义了一个接口,这个接口包含了一组方法用来生产产品,所有的具体工厂都必须实现此接口。
具体工厂 ConcreteFactory:用于生产不同产品族,要创建一个产品,用户只需使用其中一个工厂进行获取,完全不需要实例化任何产品对象。
抽象产品 AbstractProduct:这是一个产品家族,每一个具体工厂都能够生产一整组产品。
具体产品 Product
3、代码实现:

    通过抽象工厂模式,我们可以实现以下的效果:比如宝马320系列使用空调型号A和发动机型号A,而宝马230系列使用空调型号B和发动机型号B,在为320系列生产相关配件时,就无需制定配件的型号,它会自动根据车型生产对应的配件型号A。

    也就是说,当每个抽象产品都有多于一个的具体子类的时候(空调有型号A和B两种,发动机也有型号A和B两种),工厂角色怎么知道实例化哪一个子类呢?抽象工厂模式提供两个具体工厂角色(宝马320系列工厂和宝马230系列工厂),分别对应于这两个具体产品角色,每一个具体工厂角色只负责某一个产品角色的实例化,每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例。

产品类:

//发动机以及型号
public interface Engine {}

public class EngineA extends Engine{
public EngineA(){
System.out.println(“制造–>EngineA”);
}
}
public class EngineBextends Engine{
public EngineB(){
System.out.println(“制造–>EngineB”);
}
}

//空调以及型号
public interface Aircondition {}

public class AirconditionA extends Aircondition{
public AirconditionA(){
System.out.println(“制造–>AirconditionA”);
}
}
public class AirconditionB extends Aircondition{
public AirconditionB(){
System.out.println(“制造–>AirconditionB”);
}
}
创建工厂类:

//创建工厂的接口
public interface AbstractFactory {
//制造发动机
public Engine createEngine();
//制造空调
public Aircondition createAircondition();
}

//为宝马320系列生产配件
public class FactoryBMW320 implements AbstractFactory{
@Override
public Engine createEngine() {
return new EngineA();
}
@Override
public Aircondition createAircondition() {
return new AirconditionA();
}
}
//宝马523系列
public class FactoryBMW523 implements AbstractFactory {
@Override
public Engine createEngine() {
return new EngineB();
}
@Override
public Aircondition createAircondition() {
return new AirconditionB();
}
}
客户:

public class Customer {
public static void main(String[] args){
//生产宝马320系列配件
FactoryBMW320 factoryBMW320 = new FactoryBMW320();
factoryBMW320.createEngine();
factoryBMW320.createAircondition();

    //生产宝马523系列配件  
    FactoryBMW523 factoryBMW523 = new FactoryBMW523();  
    factoryBMW523.createEngine();
    factoryBMW523.createAircondition();
}  

}
工厂模式小结:

1、工厂方法模式与抽象工厂模式的区别在于:

(1)工厂方法只有一个抽象产品类和一个抽象工厂类,但可以派生出多个具体产品类和具体工厂类,每个具体工厂类只能创建一个具体产品类的实例。

(2)抽象工厂模式拥有多个抽象产品类(产品族)和一个抽象工厂类,每个抽象产品类可以派生出多个具体产品类;抽象工厂类也可以派生出多个具体工厂类,同时每个具体工厂类可以创建多个具体产品类的实例

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2022-15-Java 设计模式-抽象工厂模式 的相关文章

  • java.lang.NoClassDefFoundError:org.apache.batik.dom.svg.SVGDOMImplementation

    我在链接到我的 Android LibGDX 项目的 Apache Batik 库时遇到了奇怪的问题 但让我们从头开始 在 IntelliJ Idea 中我有一个项目 其中包含三个模块 Main Android 和 Desktop 我强调的
  • 如何为最终用户方便地启动Java GUI程序

    用户想要从以下位置启动 Java GUI 应用程序Windows 以及一些额外的 JVM 参数 例如 javaw Djava util logging config file logging properties jar MyGUI jar
  • 为什么 i++ 不是原子的?

    Why is i Java 中不是原子的 为了更深入地了解 Java 我尝试计算线程中循环的执行频率 所以我用了一个 private static int total 0 在主课中 我有两个线程 主题 1 打印System out prin
  • Final字段的线程安全

    假设我有一个 JavaBeanUser这是从另一个线程更新的 如下所示 public class A private final User user public A User user this user user public void
  • Spark 1.3.1 上的 Apache Phoenix(4.3.1 和 4.4.0-HBase-0.98)ClassNotFoundException

    我正在尝试通过 Spark 连接到 Phoenix 并且在通过 JDBC 驱动程序打开连接时不断收到以下异常 为简洁起见 下面是完整的堆栈跟踪 Caused by java lang ClassNotFoundException org a
  • 操作错误不会显示在 JSP 上

    我尝试在 Action 类中添加操作错误并将其打印在 JSP 页面上 当发生异常时 它将进入 catch 块并在控制台中打印 插入异常时出错 请联系管理员 在 catch 块中 我添加了它addActionError 我尝试在jsp页面中打
  • 如何在PreferenceActivity中添加工具栏

    我已经使用首选项创建了应用程序设置 但我注意到 我的 PreferenceActivity 中没有工具栏 如何将工具栏添加到我的 PreferenceActivity 中 My code 我的 pref xml
  • 从 127.0.0.1 到 2130706433,然后再返回

    使用标准 Java 库 从 IPV4 地址的点分字符串表示形式获取的最快方法是什么 127 0 0 1 到等效的整数表示 2130706433 相应地 反转所述操作的最快方法是什么 从整数开始2130706433到字符串表示形式 127 0
  • 在两个活动之间传输数据[重复]

    这个问题在这里已经有答案了 我正在尝试在两个不同的活动之间发送和接收数据 我在这个网站上看到了一些其他问题 但没有任何问题涉及保留头等舱的状态 例如 如果我想从 A 类发送一个整数 X 到 B 类 然后对整数 X 进行一些操作 然后将其发送
  • 仅将 char[] 的一部分复制到 String 中

    我有一个数组 char ch 我的问题如下 如何将 ch 2 到 ch 7 的值合并到字符串中 我想在不循环 char 数组的情况下实现这一点 有什么建议么 感谢您花时间回答我的问题 Use new String value offset
  • Java执行器服务线程池[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 如果我使用 Executor 框架在
  • Google App Engine 如何预编译 Java?

    App Engine 对应用程序的 Java 字节码使用 预编译 过程 以增强应用程序在 Java 运行时环境中的性能 预编译代码的功能与原始字节码相同 有没有详细的信息这是做什么的 我在一个中找到了这个谷歌群组消息 http groups
  • 如何从终端运行处理应用程序

    我目前正在使用加工 http processing org对于一个小项目 但是我不喜欢它附带的文本编辑器 我使用 vim 编写所有代码 我找到了 pde 文件的位置 并且我一直在从 vim 中编辑它们 然后重新打开它们并运行它们 重新加载脚
  • Android 中麦克风的后台访问

    是否可以通过 Android 手机上的后台应用程序 服务 持续监控麦克风 我想做的一些想法 不断聆听背景中的声音信号 收到 有趣的 音频信号后 执行一些网络操作 如果前台应用程序需要的话 后台应用程序必须能够智能地放弃对麦克风的访问 除非可
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • 编译器抱怨“缺少返回语句”,即使不可能达到缺少返回语句的条件

    在下面的方法中 编译器抱怨缺少退货声明即使该方法只有一条路径 并且它包含一个return陈述 抑制错误需要另一个return陈述 public int foo if true return 5 鉴于Java编译器可以识别无限循环 https
  • 使用 JMF 创建 RTP 流时出现问题

    我正处于一个项目的早期阶段 需要使用 RTP 广播DataStream创建自MediaLocation 我正在遵循一些示例代码 该代码目前在rptManager initalize localAddress 出现错误 无法打开本地数据端口
  • 将 List 转换为 JSON

    Hi guys 有人可以帮助我 如何将我的 HQL 查询结果转换为带有对象列表的 JSON 并通过休息服务获取它 这是我的服务方法 它返回查询结果列表 Override public List
  • 按日期对 RecyclerView 进行排序

    我正在尝试按日期对 RecyclerView 进行排序 但我尝试了太多的事情 我不知道现在该尝试什么 问题就出在这条线上适配器 notifyDataSetChanged 因为如果我不放 不会显示错误 但也不会更新 recyclerview
  • 节拍匹配算法

    我最近开始尝试创建一个移动应用程序 iOS Android 它将自动击败比赛 http en wikipedia org wiki Beatmatching http en wikipedia org wiki Beatmatching 两

随机推荐

  • Microsemi Libero使用技巧4——使用命令行模式下载程序

    文章目录 前言 关于FlashPro 关于FlashPro执行TCL脚本文件 使用命令行来烧写程序 1 添加FlashPro exe文件路径到系统环境变量 2 运行TCL脚本文件 使用bat批处理文件简化命令行操作 FlashPro下载器的
  • uniapp微信小程序开发,如何解决打包太大无法预览发布的问题

    我们经常用的解决方案有 分包 将图片上传到服务器上 减少插件引入 但是还有一个方案好多刚入门uniapp的人都给忽略了 就是在源码视图中配置 开启分包优化 1 分包 目前微信小程序可以分8个包 每个包的最大存储是2M 也就是说你文件总体的大
  • SpringBoot+Vue+POI+Mybatis-Plus+实现数据导出到Excel表格

    作者 Memory 星哥 Wechat QQ 574373426 整理不易 感谢支持 欢迎 收藏 转发 分享 专注IT职业教育多年 学编程找星哥 利用Apache POI将数据导出到Excel 技术栈 准备前端页面 创建SpringBoot
  • 解决Xavier编译ROS工程中cv_bridge找不到的问题

    0 背景 Jetson 系列Xavier 系统18 04 刷机自带opencv4 1 1版本 普通机器安装18 04系统后会自带opencv3 2版本 ROS自18 04 Melodic 不再自带opencv 依赖系统opencv 因此ro
  • spring boot+vue+nginx前后端分离详细部署过程心得!(不包含nginx集群和负载均衡)

    前期准备 spring boot项目 vue 服务器 或者linux虚拟机可联网 环境准备 服务器上有数据库 java环境即可 java会打包 vue使用build打包项目 1 安装nginx到服务器 虚拟机 下载的相关包 nginx安装包
  • Kafka各个版本差异总结

    Kafka各个版本差异总结 问题导读 1 Kafka如何做到升级不停机 2 Kafka各个版本有哪些显著变化 3 Kafka新版本设计哪些协议 Kafka 2 0 0引入了线程协议的变化 通过遵循下面建议的滚动升级计划 您可以保证在升级期间
  • python语言开发环境搭建_Python学习之路 (一)开发环境搭建-Go语言中文社区

    目录 目录 正文 前言 python3应该是Python的趋势所在 当然目前争议也比较大 这篇随笔的主要目的是记录在centos6 7下搭建python3环境的过程 以及碰到的问题和解决过程 另外 如果本机安装了python2 尽量不要管他
  • SpringCloud-服务网关

    服务网关 GateWay 核心简介 上一代zuul 1 x官网 Gateway官网 概述 Cloud全家桶中有个很重要的组件就是网关 在1 x版本中都是采用的Zuul网关 但在2 x版本中 zuul的升级一直跳票 SpringCloud最后
  • # Vue 配置前端后端路由地址

    Vue 配置前端后端路由地址 文章目录 Vue 配置前端后端路由地址 前端路由配置 配置项目地址 配置页面路由 路径跳转 后端路由配置 配后端请求地址 前端路由配置 配置项目地址 修改 config index js的配置文件 proxyT
  • jvm监控工具之jvisualvm&jmc

    一 jvisualvm 监控 方法一 使用 jstatd 1 创建策略文件 jstatd all policy 内容如下 grant codebase file java home lib tools jar permission java
  • 许奔创新社-第7问:构建创意的液态网络需要哪些条件?

    在 创意诞生的关键要素 中 我们曾提到一个非常重要的问题 对于体量差异不大的液态网络 为什么有的能产出大量高价值的创意 而剩下的却如一潭死水般无法产出分毫创意 造成此等差距的原因究竟是什么 液态网络这个词 是由创新者史蒂文 约翰逊 Stev
  • iptables 命令

    NAME iptables administration tool for IPv4 packet filtering and NAT SYNOPSIS iptables ADC 指定链的规则 A 添加 D 删除 C 修改 iptables
  • 【Neo4j】第 4 章:图形数据科学Library and Path Finding

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • Java RMI 入门

    Java RMI 入门 如何通信 实战 完整代码 Java RMI 指 JDK 内置的关于实现远程方法调用 Remote Method Invocation 的 API 这些 API 位于包 java rmi 中 通过 Java RMI 可
  • java事件监听机制(观察者设计模式的实际运用)

    package cn yang test controller java的事件监听机制和观察者设计模式 Created by Dev yang on 2016 3 1 public class Demo public static void
  • QT-MQTT客户端和服务端介绍

    MQTT Message Queuing Telemetry Transport 是一种基于发布 订阅模式的消息传递协议 在QT中使用MQTT 可以轻松地创建MQTT客户端和服务端 并实现设备之间的通信 在QT中 可以使用Qt MQTT模块
  • 7个Python有趣的lambda应用

    7个Python有趣的lambda应用 1 排序sort 2 寻找最大值max 3 查找最小值min 4 filter 5 map 6 reduce 7 Sorted 源码 1 排序sort 2 寻找最大值max 3 查找最小值min 4
  • javascript数据验证

    校验是否全由数字组成 function isDigit s var patrn 0 9 1 20 if patrn exec s return false return true 校验登录名 只能输入5 20个以字母开头 可带数字 的字串
  • 2021美赛E题

    2021年 问题E 重新优化食物系统 最近的事件向我们表明 我们的全球粮食系统即使在世界的某些地区也是不稳定的 它通常服务于全世界 这些不稳定的部分原因是我们目前的全球气候变化 庞大的国内和国际食品生产商和经销商体系 这个食物系统 使食物的
  • 2022-15-Java 设计模式-抽象工厂模式

    在工厂方法模式中 我们使用一个工厂创建一个产品 一个具体工厂对应一个具体产品 但有时候我们需要一个工厂能够提供多个产品对象 而不是单一的对象 这个时候我们就需要使用抽象工厂模式 在介绍抽象工厂模式前 我们先厘清两个概念 产品等级结构 产品等