java设计模式【抽象工厂模式】

2023-11-06

java设计模式【抽象工厂模式】

## 抽象工厂模式

抽象工厂模式是对简单工厂模式的一个变种,它允许通过一个统一的接口来创建不同的产品实例,而无需指定具体的子类。在这个模式中,我们只关心产品的抽象接口,而将具体的产品实现留给子类去实现。这样,我们可以通过创建不同的工厂对象来创建不同的产品实例,而无需关心它们实际实现的是哪个具体产品。

抽象工厂模式的实现分为以下几个步骤:

  1. 定义抽象产品接口:抽象工厂模式的核心是抽象产品接口,它定义了产品的基本结构和行为。
  2. 定义具体工厂接口:具体工厂接口是实现抽象产品接口的工厂类,它们负责创建具体产品实例。
  3. 定义工厂:每个具体工厂都是一个特定领域的工厂,它实现了抽象工厂接口,并提供了具体的产品实现。
  4. 创建产品实例:使用抽象工厂接口,客户端可以创建不同的产品实例,而无需指定具体的子类。

优缺点

优点:

  1. 具体产品在应用层的代码隔离,无需关系创建的细节。
  2. 将一个系列的产品统一到一起创建,方便产品族的扩展。
  3. 提供一个产品类的库,所有的产品以同样的接口出现,使得客户端不依赖于具体实现。
  4. 通过创建不同的工厂对象来创建不同的产品实例,无需关心它们实际实现的是哪个具体产品。

缺点:

  1. 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难。
  2. 增加了系统的抽象性和理解难度。
  3. 使用场景:客户端(应用层)不依赖与产品类的实现等细节。
  4. 需要大量的重复代码,增加了开发和维护的成本。

使用场景

  1. 一个系统要独立于它的产品的创建、组合和表示时。
  2. 一个系统要由多个产品系列中的一个来配置时。
  3. 需要强调一系列相关的产品对象的设计以便进行联合使用时。
  4. 提供一个产品类库,而只想显示它们的接口而不是实现时。
  5. 产品之间相互关联、相互依赖且相互约束的地方。

具体实现

以下以智能产品汽车和手机为例,继承关系如下:

继承关系图

定义抽象工厂

/**
 * 智能产品抽象工厂
 */
public interface SmartProductFactory {

    ISmartPhone createSmartPhone();

    ISmartCar createSmartCar();

}

具体工厂

/**
 * @author physicx
 * @date 2023/5/17 上午11:18
 * @desc 华为工厂
 * Created with IntelliJ IDEA
 */
public class HuaweiFactory implements SmartProductFactory {
    @Override
    public ISmartPhone createSmartPhone() {
        return new HuaweiSmartPhone();
    }

    @Override
    public ISmartCar createSmartCar() {
        return new HuaweiSmartCar();
    }
}
/**
 * @author guogq
 * @date 2023/5/17 上午11:18
 * @desc 小米工厂
 * Created with IntelliJ IDEA
 */
public class XiaomiFactory implements SmartProductFactory {
    @Override
    public ISmartPhone createSmartPhone() {
        return new XiaomiSmartPhone();
    }

    @Override
    public ISmartCar createSmartCar() {
        return new XiaomiSmartCar();
    }
}

定义抽象产品

/**
 * 智能手机
 */
public interface ISmartPhone {

    void printInfo();

}
/**
 * 智能汽车
 */
public interface ISmartCar {
    void printInfo();
}

具体产品

/**
 * @author physicx
 * @date 2023/5/17 上午11:19
 * @desc 华为智能汽车
 * Created with IntelliJ IDEA
 */
public class HuaweiSmartCar implements ISmartCar {
    @Override
    public void printInfo() {
        System.out.println("华为智能汽车");
    }
}
/**
 * @author guogq
 * @date 2023/5/17 上午11:19
 * @desc 华为智能手机
 * Created with IntelliJ IDEA
 */
public class HuaweiSmartPhone implements ISmartPhone {
    @Override
    public void printInfo() {
        System.out.println("华为智能手机");
    }
}
/**
 * @author guogq
 * @date 2023/5/17 上午11:19
 * @desc 小米智能汽车
 * Created with IntelliJ IDEA
 */
public class XiaomiSmartCar implements ISmartCar {
    @Override
    public void printInfo() {
        System.out.println("小米智能汽车");
    }
}
/**
 * @author guogq
 * @date 2023/5/17 上午11:19
 * @desc 小米智能手机
 * Created with IntelliJ IDEA
 */
public class XiaomiSmartPhone implements ISmartPhone {
    @Override
    public void printInfo() {
        System.out.println("小米智能手机");
    }
}

客户端调用

public static void main(String[] args) {
        HuaweiFactory huaweiFactory = new HuaweiFactory();
        huaweiFactory.createSmartPhone().printInfo();
        huaweiFactory.createSmartCar().printInfo();

        XiaomiFactory xiaomiFactory = new XiaomiFactory();
        xiaomiFactory.createSmartPhone().printInfo();
        xiaomiFactory.createSmartCar().printInfo();
    }

打印如下:

运行结果

工厂方法模式和抽象工厂模式区别

工厂方法模式和抽象工厂模式都是创建型模式,区别如下:

  1. 工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
  2. 工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
  3. 工厂方法模式的使用很简单,只要继承成子类,并实现工厂方法的工厂就可以了,而抽象工厂模式需要先实例化它,然后将它传入一些针对抽象类型所写的代码中。
  4. 工厂方法模式的优点是可以把一群相关的产品集合起来,而抽象工厂模式的优点是可以把一群相关的产品集合起来,并且创建整个产品家族的模式。

总之,工厂方法是由子类自行决定实例化那个类,而抽象工厂是自己决定实例化哪个类。至于是组合还是继承还是实现接口都无所谓。根本区别在于是自己实例化还是子类实例化。

如果产品单一,只有一个产品等级结构适合使用工厂方法模式。如果存在多个产品等级,产品分类多个可以形成产品族合适使用抽象工厂模式。

补充说明

后续会依次更新 详解java 23种设计模式,欢迎关注、交流、补充相关内容(如下)。

快捷导航
设计模式简介总结
单例模式详解
工厂方法模式详解
抽象工厂模式详解
原型模式
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java设计模式【抽象工厂模式】 的相关文章

  • Java 扫描仪问题 (JFrame)

    我正在尝试使用扫描仪来编辑塔防游戏的级别 但是 它不会将级别 图块图像 更新为自定义文件的级别 0 是草 1 是石头 1 是什么都没有 等等 我发现了错误 但如何修复它 我需要添加 更改什么才能消除这个错误 java lang NullPo
  • 如何为带有未确定的“?”的Java通用Map添加值值类型?

    我在 JDK 8 示例中看到过这种声明 Map
  • Android - 检测电容式触摸屏上的触摸压力?

    我听说过 MotionEvent e float press e getPressure 但这只会在没有触摸时返回 0 当我的手指触摸屏幕时返回 1 是否可以找到手指在触摸电容屏上施加的压力值 或者我的预感是否正确 即这只适用于电阻屏幕 M
  • 为 Nimbus 外观设计简单的单元渲染器

    我有一个简单的单元格渲染器 它由一些组成JLabels 渲染器本身扩展JPanel 并且我正在尝试让它在 Nimbus 的外观和感觉中合理地渲染 基本上发生的事情是在lighter行 正如 Nimbus 所具有的交替行着色 我的特定单元格渲
  • 在 Spring 中使用事务时创建提交后

    由于某些原因 我使用 Spring PlatformTransactionManager 手动执行事务提交和回滚 我需要做的是设置一个钩子 以便在提交事务后发生提交后操作 通过查看 void commit TransactionStatus
  • 我在 Android Studio 中使用哪个版本的 JDK 有关系吗?

    I know I can choose the SDK location in Android Studio s Project Structure 我有两个问题 当我们已经使用Android SDK时 为什么还需要JDK 毕竟我们不是为
  • 如何设置Java线程的CPU核心亲和力?

    我搜索了以前关于类似主题的帖子 但找不到合适的答案 因此提出这个问题 非常感谢您帮助回答 我知道在 Linux 中通过任务集命令设置进程与特定 CPU 核心的关联性 但我想设置 Java 线程与特定 cpu 核心的亲和力 以便属于同一进程的
  • CreationException:无法在 Play 2.5.18 中创建注入器错误,以使用 com.google.inject.AbstractModule 替换 GlobalSettings Java 代码

    我正在将 Play 应用程序从 2 5 12 升级到 2 5 18 当我启动该应用程序时 使用sbt 我收到此错误 CreationException 无法创建注入器 看到以下错误 1 Error injecting constructor
  • Java setLocation() 事故

    我正处于创建一个程序来操作员工 客户系统的开始阶段 现在我刚刚创建了登录 GUI 但我遇到了一些问题 setLocation 方法 我将其设置为 250 250 但这使我的 GUI 高度变得非常疯狂 如果有人能够解决这个问题 我的代码如下
  • Java SSO 与 Wildfly 8、Java 1.8.0_45 和 Active Directory

    我对这个主题进行了很多搜索 但找不到解决方案 要求的简短描述 Wildfly 8 2 下 Web 应用程序上的 SSO 在 Active Directory 中验证 Windows 用户的身份 当 SSO 失败时回退到登录表单 在 Wild
  • 在Java中打印时差最惯用的方法是什么?

    我熟悉以毫秒为单位的打印时间差 long time System currentTimeMillis do something that takes some time long completedIn System currentTime
  • Jlist 自定义渲染器

    我正在尝试添加一个我猜你会称其为列表中每个项目的子列表 我构建了一个自定义渲染器 它提供以下输出 正如你所看到的 有些东西不对劲 我没能找到问题的答案 我猜我需要更改面板布局中的某些内容才能获得正确的结果 但不知道是什么 https i s
  • 使用 GSON 将 JSON 字符串转换为 Java 对象

    我正在尝试将 json 解析为 java 根据 jsonlint com 我有以下字符串 该字符串是有效的 json private final static String LOC JSON lat1 39 737567 lat2 32 7
  • Spring Hibernate中的@Transient方法调用

    我有一个 Pojo 类 在其中创建一个未与数据库表映射的字段 所以我必须声明字段Declaration和setter和getter方法 Transient 否则会显示错误 Transient private String docHistor
  • 是否有适合 Java 1.4 和 SE (Swing) 应用程序的优秀 DI 框架?

    我正在寻找一个适用于在 JDK 1 4 下运行的 Java SE Swing 应用程序的依赖注入框架 有没有我可以使用的推荐 DI 框架 Guice 和其他基于注释的框架已经退出 我不想搞乱像 Retroweaver 这样的东西 另外 Sp
  • Android 自定义相机 - 在矩形内裁剪图像

    我有一个自定义相机应用程序 它有一个居中的矩形视图 如下所示 当我拍照时 我想忽略矩形之外的所有内容 该视图与我的 XML 视图中的 Camera Preview 或 SurfaceView 没有任何联系 如下所示
  • 从java小程序获取正确的本地IP地址

    我想从我的 java 小程序确定本地 IP 地址 问题是当同一台机器上有多个 IP 地址时 该机器具有 LAN 和互联网连接 掌上电脑 VMWare 这是我的测试 public static void main String args tr
  • 在 Groovy 中将整数转换为 BigDecimal

    假设我们有一个 groovy 函数作为参数BigDecimal void func BigDecimal bd 并在 groovy 的其他课程中再次调用它var func 0 这工作正常 但在 java 中它根本无法编译 我知道有一个构造函
  • 将菜单添加到空活动

    我在 Android Studio 中制作了一个 Android 应用程序 并想在其上创建一个选项菜单 我将其创建为一个空活动 现在意识到我最好创建一个空白活动来获取选项菜单 无论如何 是否可以在空活动中创建选项菜单 如果有人能给我指出一个
  • 应用程序中 GC 长时间暂停

    我当前运行的应用程序需要最大堆大小为 16GB 目前我使用以下标志来处理垃圾收集 XX UseParNewGC XX UseConcMarkSweepGC XX CMSInitiatingOccupancyFraction 50 XX Di

随机推荐

  • 2021-11-14

    艰难安装pyspider 环境 WIN10 python3 6 这个pyspider搞了我两天终于安装好了 1 首先把安装好的库全部删除 python pip freeze gt allpackages txt pip uninstall
  • yolov5训练l模型报错解决方案

    yolov5训练l模型报错解决方案 关于配置YOLOV5时出现错误 AttributeError Can t get attribute C3 on module models common from AttributeError Can
  • Git从入门到起飞(详细)

    Git从入门到起飞 Git从入门到起飞 什么是Git 使用git前提 注册git 下载Git 在Windows上安装Git 在macOS上安装Git 在Linux上安装Git 配置Git 配置全局用户信息 配置文本编辑器 创建第一个Git仓
  • libevent源码学习(12):超时管理之common_timeout

    目录 前言 common timeout的作用 common timeout的结构定义 common timeout与一般timeout的区分 获取common timeout在common timeout queues中的下标 判断一个t
  • 解决Github,jetbrains(IDEA)网站访问缓慢(借鉴源文已删)

    1 获取Github的ip地址 通过访问 https www ipaddress com 这个网站来获取当前github最新的ip地址 2 修改 host 文件 文件路径 C Windows System32 drivers etc hos
  • Tomcat日志设定

    1 Tomcat 日志概述 Tomcat 日志信息分 为 两 类 一是运行中的日志 它主要 记录 运行的一些信息 尤其是一些异常 错误 日志信息 二是 访问 日志信息 它 记录 的 访问 的 时间 IP 访问 的 资 料等相 关 信息 2
  • 提高SQL SERVER运行速度的方法

    数据库的整体性能的提高分为以下几种情况 1 库结构设计合理 可通过合适索引等常用方式来进行优化 2 优化查询语句 视图 存储过程 其他一般的查询SQL 3 改进库结构设计 达到根本的解决常规性能低下的目的 4 分布式系统构架 5 确保高性能
  • Android快速转战Kotlin教程,先收藏了

    前言 就要到 金九银十 面试跳槽季了 需要找工作的小伙伴们该要着手开始复习了 特此将我今年收录的一些腾讯 阿里巴巴 字节跳动等等一线互联网巨头的面试真题体系的归类 整理了一下 拿来出分享给大家 希望能给有需要的小伙伴一些力所能及的帮助 也希
  • Canvas和SVG有什么区别?

    svg绘制出来的每一个图形的元素都是独立的DOM节点 能够方便的绑定事件或用来修改 canvas输出的是一整幅画布svg输出的图形是矢量图形 后期可以修改参数来自由放大缩小 不会失真和锯齿 而canvas输出标量画布 就像一张图片一样 放大
  • 文件下载响应头 header 属性设置

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 在服务端处理文件下载时 其实操作起来并不复杂 只有两步就可以完成下载操作 第一步 设置响应头 const header Content Type application o
  • 微信小程序渐变色

    CSS3 渐变 gradients 可以在两个或多个指定的颜色之间显示平稳的过渡 CSS3 定义了两种类型的渐变 gradients 线性渐变 Linear Gradients 向下 向上 向左 向右 对角方向 径向渐变 Radial Gr
  • 可以远程的pe系统

    下载 GlassPE https glasspe cn firpe https firpe cn page 247 HotPE https www hotpe top 优启通 https www itsk com topic softwar
  • Json获取字段

    某接口返回的response code 0 msg success data domIdList 163 165 atrol test1 reportList createTime 2022 06 22 15 34 01 reportId
  • 超详细解析Spring Boot自动装配原理

    Spring Boot的自动装配原理 易懂 熟练使用Spring Boot那么自动装配原理的掌握是必不可少的 一 自动装配是什么 Spring Boot的自动装配实际上是从META INF spring factories文件中获取到对应的
  • 服务器怎么用sata做系统盘,服务器sas硬盘+sata串口硬盘win2003系统安装方法

    nraid nraid即non raid 所有磁盘的容量组合成一个逻辑盘 没有数据块分条 no block stripping nraid不提供数据冗余 要求至少一个磁盘 jbod jbod代表just a bunch of drives
  • win10系统连接win7共享打印机

    win10系统自动升级后 网络打印机忽然连不上了 打印机连着的win7总是拒绝我访问 连接的时候提示 你不能访问此共享文件夹 因为你组织的安全策略阻止未经身份验证的来宾访问 这些策略可帮助保护你的电脑免受网络上不安全设备或恶意设备的威胁 其
  • LINUX下面NetworkManager和network冲突的问题

    首先不知道怎么情况重启了一下机器然后发现自己的eth0网卡启动不成功 显示错误信息 弹出界面AUTO EHT0 Device not managed by NetworkManager or unavailable 之后自己尝试了好多方法
  • git使用X篇_1_SVN和GIT的版本控制区别及git等的使用方法

    GIT是分布式版本控制系统 可以在本地记录代码的修改过程而不一定上传至SVN服务端 详细使用差异见博客 版本控制 SVN和GIT的一些使用感受 版本控制 SVN和GIT的一些使用感受 续 git svn SVN和GIT的版本控制区别及git
  • 【Node Sass version 8.0.0 is incompatible with ^4.0.0.问题解决】

    Node Sass version 8 0 0 is incompatible with 4 0 0 问题解决 1 问题起源 在微信小程序Vue搭建安装依赖后 重新运行项目出现错误 此时无法继续运行项目 观察package json可以发现
  • java设计模式【抽象工厂模式】

    文章目录 java设计模式 抽象工厂模式 优缺点 使用场景 具体实现 定义抽象工厂 具体工厂 定义抽象产品 具体产品 客户端调用 工厂方法模式和抽象工厂模式区别 补充说明 java设计模式 抽象工厂模式 抽象工厂模式 抽象工厂模式是对简单工