【设计模式】JAVA Design Patterns——Abstract Factory(抽象工厂模式)

news2024/12/26 20:46:30

🔍目的


提供一个用于创建相关对象家族的接口,而无需指定其具体类

🔍解释

真实世界例子


要创建一个王国,我们需要具有共同主题的对象。精灵王国需要精灵国王、精灵城堡和精灵军队,而兽人王国需要兽人国王、兽人城堡和兽人军队。王国中的对象之间存在依赖关系。

通俗的说


 一个将单个但相关/从属的工厂分组在一起而没有指定其具体类别的工厂。

维基百科


抽象工厂模式提供了一种封装一组具有共同主题的单个工厂而无需指定其具体类的方法

程序实例


按照上述的真实世界案例。首先,我们为王国中的对象提供了一些接口和实现。

public interface Castle {
  String getDescription();
}

public interface King {
  String getDescription();
}

public interface Army {
  String getDescription();
}

// Elven implementations ->
public class ElfCastle implements Castle {
  static final String DESCRIPTION = "This is the Elven castle!";
  @Override
  public String getDescription() {
    return DESCRIPTION;
  }
}
public class ElfKing implements King {
  static final String DESCRIPTION = "This is the Elven king!";
  @Override
  public String getDescription() {
    return DESCRIPTION;
  }
}
public class ElfArmy implements Army {
  static final String DESCRIPTION = "This is the Elven Army!";
  @Override
  public String getDescription() {
    return DESCRIPTION;
  }
}

// Orcish implementations similarly -> ...

然后我们有了王国工厂的抽象和实现 

public interface KingdomFactory {
  Castle createCastle();
  King createKing();
  Army createArmy();
}

public class ElfKingdomFactory implements KingdomFactory {
  public Castle createCastle() {
    return new ElfCastle();
  }
  public King createKing() {
    return new ElfKing();
  }
  public Army createArmy() {
    return new ElfArmy();
  }
}

public class OrcKingdomFactory implements KingdomFactory {
  public Castle createCastle() {
    return new OrcCastle();
  }
  public King createKing() {
    return new OrcKing();
  }
  public Army createArmy() {
    return new OrcArmy();
  }
}

我们可以制作相关对象的系列,即精灵王国工厂创建了精灵城堡,国王和军队等。 

var factory = new ElfKingdomFactory();
var castle = factory.createCastle();
var king = factory.createKing();
var army = factory.createArmy();

castle.getDescription();
king.getDescription();
army.getDescription();

程序输出

This is the Elven castle!
This is the Elven king!
This is the Elven Army!

 我们可以为不同的王国工厂设计工厂。 在此示例中,我们创建了FactoryMaker,负责返回ElfKingdomFactory或OrcKingdomFactory的实例。 客户可以使用FactoryMaker来创建所需的具体工厂,该工厂随后将生产不同的具体对象(军队,国王,城堡)。 在此示例中,我们还使用了一个枚举来参数化客户要求的王国工厂类型。

public static class FactoryMaker {

    public enum KingdomType {
        ELF, ORC
    }

    public static KingdomFactory makeFactory(KingdomType type) {
        return switch (type) {
            case ELF -> new ElfKingdomFactory();
            case ORC -> new OrcKingdomFactory();
            default -> throw new IllegalArgumentException("KingdomType not supported.");
        };
    }
}

    public static void main(String[] args) {
        var app = new App();

        LOGGER.info("Elf Kingdom");
        app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
        LOGGER.info(app.getArmy().getDescription());
        LOGGER.info(app.getCastle().getDescription());
        LOGGER.info(app.getKing().getDescription());

        LOGGER.info("Orc Kingdom");
        app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
        --similar use of the orc factory
    }

🔍类图

Abstract Factory class diagram 

🔍适用场景

1.该系统应独立于其产品的创建,组成和表示方式

2.系统应配置有多个产品系列之一

3.相关产品对象系列旨在一起使用,你需要强制执行此约束

4.你想提供产品的类库,并且只想暴露它们的接口,而不是它们的实现。

5.从概念上讲,依赖项的生存期比使用者的生存期短。

6.你需要一个运行时值来构建特定的依赖关系

7.你想决定在运行时从系列中调用哪种产品。

8.你需要提供一个或更多仅在运行时才知道的参数,然后才能解决依赖关系。

9.当你需要产品之间的一致性时

10.在向程序添加新产品或产品系列时,您不想更改现有代码。

🔍后果

1.Java中的依赖注入会隐藏服务类的依赖关系,这些依赖关系可能导致运行时错误,而这些错误在编译时会被捕获。

2.虽然在创建预定义对象时模式很好,但是添加新对象可能会很困难。

3.由于引入了许多新的接口和类,因此代码变得比应有的复杂。


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

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

相关文章

业务系统加固和安全设备加固

业务系统加固 业务系统包含哪些系统? 业务系统漏洞面临的风险 1web风险 2漏洞扫描,端口扫描 3系统漏洞 4逻辑漏洞 5 信息泄露 6拒绝服务 7口令爆破 加固方式: 在风险加上修复 1web漏洞: 包括csrf,xss,口令破解等等 修…

STM32学习和实践笔记(28):printf重定向实验

1.printf重定向简介 在C语言中printf函数里,默认输出设备是显示器,如果想要用这个函数将输出结果到串口或者LCD上显示,就必须重定义标准库函数里中printf函数调用的与输出设备相关的函数。 比如要使用printf输出到串口,需要先将f…

java—数据库批量插入数据

前言 本篇文章将记录几种使用java向mysql数据库中批量插入数据的方法,比如插入1000条,10000条,10万条甚至100万条数据。操作数据库的方式采用Mybatis框架。 输入的数据: 现数据库有一个student表,表中字段如下&…

手撸XXL-JOB(二)——定时任务管理

在上一节中,我们介绍了SpringBoot中关于定时任务的执行方式,以及ScheduledExecutorService接口提供的定时任务执行方法。假设我们现在要写类似XXL-JOB这样的任务调度平台,那么,对于任务的管理,是尤为重要的。接下来我们…

讲解SSM的xml文件

概述&#xff1a;这些配置文件很烦&#xff0c;建议直接复制粘贴 springMVC.xml文件 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XM…

k8s endpoint

Endpoint Service 并不是和 pod 直接相连的&#xff0c;Endpoint 介于两者之间。Endpoint 资源就是暴露一个服务的 IP 地址和端口的列表。 虽然在 spec 服务中定义了 pod 选择器&#xff0c;但在重定向传入连接时不会直接使用它。选择器用于构建 IP 和端口列表&#xff0c;然…

SQOOP详细讲解

SQOOP安装及使用 SQOOP安装及使用SQOOP安装1、上传并解压2、修改文件夹名字3、修改配置文件4、修改环境变量5、添加MySQL连接驱动6、测试准备MySQL数据登录MySQL数据库创建student数据库切换数据库并导入数据另外一种导入数据的方式使用Navicat运行SQL文件导出MySQL数据库impo…

企业必看:镭速教你如何测试内网文件传输效率和稳定问题

在现代商业运作中&#xff0c;企业内部文件传输的效率和稳定性对于数据管理和业务流程极为重要。无论是远程工作还是团队协作&#xff0c;高效的文件传输都能显著提升工作效率。今天镭速小编就教你如何测试内网文件传输效率和稳定问题。 1、磁盘性能&#xff0c;即硬盘的读取和…

JVM从1%到99%【精选】-运行时数据区

目录 1.总览运行时数据区 2.内存溢出 3. 程序计数器 4.虚拟机栈 5.本地方法栈 6.堆 7.方法区 8.直接内存 1.总览运行时数据区 Java虚拟机在运行Java程序过程中管理的内存区域,称之为运行时数据区。运行时数据区可以分为方法区、堆、虚拟机栈、本地方法栈、程序计数器…

分享一些关于软件测试的面试问题

由于最近在面试软件测试工程师的岗位&#xff0c;遇到了一些面试的问题以及我的答案&#xff0c;希望对正在找工作的同行有些帮助&#xff0c;仅仅作为软件测试行业&#xff0c;求职者看问题就行&#xff0c;大佬可以探讨一下答案。 1.提交了bug&#xff0c;开发不认为是bug怎么…

JavaScript的综合案例

案例要求&#xff1a; 实现一个表单验证 1.当输入框失去焦点时&#xff0c;验证输入的内容是否符合要求 2.当点击注册按钮时&#xff0c;判断所有输入框的内容是否都符合要求&#xff0c;如果不符合要求阻止表单提交 简单的页面实现 <!DOCTYPE html> <html lang&…

凸优化理论学习三|凸优化问题(一)

系列文章目录 凸优化理论学习一|最优化及凸集的基本概念 凸优化理论学习二|凸函数及其相关概念 文章目录 系列文章目录一、优化问题&#xff08;一&#xff09;标准形式的优化问题&#xff08;二&#xff09;可行点和最优点&#xff08;三&#xff09;局部最优点&#xff08;四…

【万字面试题】Redis

文章目录 常见面试题布隆过滤器原理和数据结构&#xff1a;特点和应用场景&#xff1a;缺点和注意事项&#xff1a;在python中使用布隆过滤器 三种数据删除策略LRU (Least Recently Used)工作原理&#xff1a;应用场景&#xff1a; LFU (Least Frequently Used)工作原理&#x…

振弦式应变计的灵敏系数k范围探讨

振弦式应变计是一种广泛应用于工程结构健康监测的重要设备&#xff0c;其灵敏系数k是衡量其性能的关键指标。本文将探讨振弦式应变计的灵敏系数k的一般范围&#xff0c;并分析影响灵敏系数的因素。 一、振弦式应变计的工作原理 振弦式应变计通过测量振弦在受力作用下的振动频率…

屡被约谈的货拉拉三闯IPO,CEO周胜馥IPO前套现11亿

近日&#xff0c;货运巨头货拉拉第三次闯关IPO。虽然其实现首次年度盈利&#xff0c;但光鲜数据背后的盈利模式却频遭诟病。 货拉拉的创始人周胜馥从美国高校毕业后&#xff0c;曾供职于贝恩咨询公司&#xff0c;并在期间对创业产生了浓厚兴趣。抛开履历中的高学历好工作的部分…

Amesim基础篇-表格类型设置与读取

前言 在Amesim仿真中,不可避免需要应用到表格。如新能源动力电池中内阻、充电倍率的调取,压缩机的机械效率、容积效率等,水泵的效率,管路的压降等等。本文将介绍如何对表格类型的选择与参数输入。 1 进入表格设置界面 如下图所示,在Amesim界面的右上角Table Editor进入…

EEL中 python端的函数名是如何传递给js端的

python端的函数名是如何传递给js端的 核心步骤&#xff1a;将函数名列表注入到动态生成的 eel.js 中&#xff0c;这样前端一开始引用的eel.js本身已经包含有py_function的函数名列表了。你打开开发者工具看看浏览器中的 eel.js文件源代码就知道了。 具体实现&#xff1a; # 读…

使用 Flask Blueprint 实现模块化 Web 应用

文章目录 1. 什么是 Flask Blueprint&#xff1f;2. 为什么要使用 Flask Blueprint&#xff1f;3. 如何使用 Flask Blueprint&#xff1f;4. 在 Blueprint 之间进行通信5. 结合 Flask 插件系统进行功能拓展结语 当构建大型 Flask Web 应用时&#xff0c;保持代码的组织结构清晰…

etcd单机部署和集群部署

1、etcd单实例部署 对于平常的学习&#xff0c;其实搭建一个单机节点是够了的。接下来就讲讲怎么搭建单机节点。 本次部署是在 centos7 系统&#xff0c;cpu 为amd64 上面进行的。 部署是直接使用官方编译好的二进制文件&#xff0c;大家也可以直接看 ectd-releases 界面选择…

linux 环境下 分布式文件搭建fastDFS

1.软件信息 地址&#xff1a;happyfish100 (YuQing) GitHub 1.fastdfs-master.zip 2.fastdfs-nginx-module-master.zip 3.libfastcommon-master.zip 4.libserverframe-master.zip yum install make cmake gcc gcc-c perl 2.安装libfastcommon unzip libfastcommon-mast…