【设计模式】创建型-抽象工厂模式

文章目录

  • 一、抽象工厂模式
    • 1.1、产品族、产品等级
    • 1.2、抽象工厂模式中的角色
    • 1.3、实例


一、抽象工厂模式

在工厂方法模式中,每一个具体的工厂子类只能生成一种具体的产品,如果想要生产另外一种产品,就需要重新定义一个抽象工厂类,这样的拓展性还是会有点不足,而抽象工厂模式则是可以一个具体工厂可以生产不同的产品。

在学习抽象工厂模式之前先了解一下 产品族和产品等级 这两个概念

1.1、产品族、产品等级

  • 产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中,海尔电视机、海尔电冰箱构成了一个产品族。
  • 产品等级结构产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。

在这里插入图片描述

当系统所提供的工厂生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构、属于不同类型的具体产品时就可以使用抽象工厂模式。抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形式。抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的 产品对象的创建。当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、更有效率。

在这里插入图片描述

1.2、抽象工厂模式中的角色

在抽象工厂模式结构中包含如下几个角色:

  • AbstractFactory(抽象工厂):它声明了一组用于创建一族产品的方法,每一个方法对应一种产品。
  • ConcreteFactory(具体工厂):它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。
  • AbstractProduct(抽象产品):它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。
  • ConcreteProduct(具体产品):它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。

1.3、实例

就拿上面电视机、冰箱、空调为例:

  • 抽象产品类:

    • 电视机抽象产品类:
    public interface Television {
        public void viewTV(); // 电视机的抽象方法 -> 看电视
    }
    
    • 空调产品抽象类:
    public interface AirConditoner {
        public void changeTemperature();// 空调的抽象方法 -> 改变温度
    }
    
  • 具体产品类:

    • 电视机:

      • 海尔电视机类:
        public class HaierTelevision implements Television {
            public void viewTV() {
                // 海尔电视机看电视的方法
            }
        }
        
      • TCL电视机类:
        public class TCLTelevision implements Television {
          public void viewTV() {
              // TCL电视机看电视的方法
          }
        }
        
    • 空调:

      • 海尔空调类
        public class HaierAirConditioner implements AirConditioner {
            public void changeTemperature(){
                // 海尔空调改变温度的方法
            }
        }
        
      • TCL空调类
        public class TCLAirConditioner implements AirConditioner {
            public void changeTemperature(){
                // TCL空调改变温度的方法
            }
        }
        
  • 抽象工厂:根据整个产品分析,这些产品都是电器类,所以创建一个电器抽象工厂,电器工厂可以创建电视机、冰箱、空调

    public interface EFactory {
        public Television produceTelevision(); // 生产电视机的工厂方法
        public AirConditioner produceAirConditioner(); // 生产空调的工厂方法
    }
    
  • 具体工厂:根据产品族分为三个不同的具体工厂

    • 海尔工厂:
      public class HaierFactory implements EFactory {
          // 生产电视机的工厂方法
          public Television produceTelevision(){
              return new HaierTelevision(); // 创建海尔品牌的电视机
          }
          // 生产空调的工厂方法
          public AirConditioner produceAirConditioner(){
              return new HaierAirConditioner(); // 创建海尔品牌的空调
          }
      }
      
    • TCL工厂:
      public class TCLFactory implements EFactory {
          // 生产电视机的工厂方法
          public Television produceTelevision(){
              return new TCLTelevision(); // 创建海尔品牌的电视机
          }
          // 生产空调的工厂方法
          public AirConditioner produceAirConditioner(){
              return new TCLAirConditioner(); // 创建海尔品牌的空调
          }
      }
      
  • 客户端:假设我想生产海尔品牌的电视机和空调,那么代码如下:

    public class Client {
        public static void main(String args) {
            // 既然是需要海尔品牌的,那就需要创建海尔品牌的工厂对象
            EFactory factory = new HaierFactory();
            // 然后调用工厂中的工厂方法就可以生产出想要的产品了
            Television television = factory.produceTelevision(); // 生产海尔品牌的电视机
            AirConditioner airConditioner = factory.produceAirConditioner();// 生产海尔品牌的空调
        }
    }
    

这样就完成了一个抽象工厂模式的设计,但是在其中我们可以发现,在抽象工厂模式中,增加产品族,也就是增加一个具体子工厂很容易,也不会违背 开闭原则,但是增加新的产品等级需要修改所有的工厂角色,包括抽象工厂类,在所有的工厂类中都需要增加生产新产品的方法,违背了“开闭原则”。这种现象被称为 开闭原则的倾斜性

正因为抽象工厂模式存在“开闭原则”的倾斜性,它以一种倾斜的方式来满足“开闭原则”,为增加新产品族提供方便,但不能为增加新产品结构提供这样的方便,因此要求设计人员在设计之初就能够全面考虑,不会在设计完成之后向系统中增加新的产品等级结构,也不会删除已有的产品等级结构,否则将会导致系统出现较大的修改,为后续维护工作带来诸多麻烦。

所以,抽象工厂模式的优缺点:

  • 优点:
    • 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易,所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。
    • 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
    • 增加新的产品族很方便,无须修改已有系统,符合“开闭原则”。
  • 缺点:
    • 增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了“开闭原则”。

使用场景:

  • 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是很重要的,用户无须关心对象的创建过程,将对象的创建和使用解耦。
  • 系统中有多于一个的产品族,而每次只使用其中某一产品族。可以通过配置文件等方式来使得用户可以动态改变产品族,也可以很方便地增加新的产品族。
  • 属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。同一个产品族中的产品可以是没有任何关系的对象,但是它们都具有一些共同的约束,如同一操作系统下的按钮和文本框,按钮与文本框之间没有直接关系,但它们都是属于某一操作系统的,此时具有一个共同的约束条件:操作系统的类型。
  • 产品等级结构稳定,设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue3中父子表单组件数据同步问题

前言: 有段时间没有更新文章了,最近工作中遇到某个Vue表单文件复杂度代码行数高达5K,为此页面更新时有些许卡顿,当时决定将这个Vue表单文件抽离成几个小表单的结构,便于今后的项目维护和功能迭代。 所以今天给大家带…

python外篇(魔术方法)

目录 归类 new和init str和repr 是否需要实现 自实现with open 具体的官方文档学习链接放前面: https://docs.python.org/3/reference/datamodel.html#special-method-names 归类 ### 1. 对象表示相关的魔术方法: __str__(self):返…

【C语言】一篇带你了解 柔性数组的意义与如何使用

文章目录柔性数组柔性数组的特点:柔性数组的使用柔性数组的优势柔性数组 也许你从来没有听说过柔性数组(flexible array)这个概念,但是它确实是存在的。C99 中,结构中的最后一个元素允许是未知大小的数组,这…

计算机信息安全有哪些SCI期刊推荐? - 易智编译EaseEditing

以下是计算机信息安全方向的SCI期刊推荐: IEEE Transactions on Information Forensics and Security 该期刊主要发表信息安全和数字取证方面的原创性研究,包括数据安全、网络安全、身份认证、加密、信息隐藏等领域的研究成果。该期刊的影响因子为8.134…

想成为一名【黑客】,你该如何快速的入门?

假设你有一台个人电脑,或者可以访问一台电脑,那么你就可以着手【黑客】技能的学习了。【黑客】文化演化而来的的时候,电脑是很昂贵的,个人不能拥有他们。所以最重要的一个步骤就是新手可以拥有一台属于自己的电脑,新手…

SpringBoot简介

SpringBoot简介1,SpringBoot简介1.1 SpringBoot快速入门1.1.1 开发步骤1.1.1.1 创建新模块1.1.1.2 创建 Controller1.1.1.3 启动服务器1.1.1.4 进行测试1.1.2 对比1.1.3 官网构建工程1.1.3.1 进入SpringBoot官网1.1.3.2 选择依赖1.1.3.3 生成工程1.1.4 SpringBoot工…

【面试】面试官问的几率较大的网络安全面试题

文章目录防范常见的 Web 攻击1、什么是SQL注入攻击2、什么是XSS攻击3、什么是CSRF攻击4、什么是文件上传漏洞5、DDos 攻击重要协议分布图1、arp协议的工作原理ARP协议工作原理:2、什么是RARP?工作原理3、dns是什么?dns的工作原理4、rip协议是…

Java初阶 ( String 类)

文章目录一、String 类的基础概念1.1 Java 中的字符串1.2 字符串的构造二、String 类的进阶概念2.1 求字符串的长度2.2 isEmpty()2.3 字符串的比较2.4 字符串的查找2.5 字符串的转换2.6 字符串的替换2.6 字符串的拆分2.7 字符串的截取2.8 去掉字符串的左右空白字符2.9 StringBu…

【新2023Q2押题JAVA】华为OD机试 - 打折买水果

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:打折买水果 题目 有 m m m…

浅谈JVM(二):类加载机制

上一篇: 浅谈JVM(一):Class文件解析 类加载机制 ​ Java虚拟机把类的描述数据从Class文件加载到内存,并对数据进行校验、转换解析、初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程就是虚拟机的类加载机制。…

【Redis】redis跟数据库的数据同步问题

文章目录一、Redis 数据库数据一致性的解决方案1.1、更新Redis缓存、删除Redis缓存的区别二、先删Redis缓存、后删Redis缓存会产生什么问题?解决方案?2.1、删除Redis缓存,再更新数据库2.2、解决方案2.3、先更新数据库,再删除Redis…

【蓝桥杯】【嵌入式组别】第八节:EEPROM

EEPROMIIC协议简介:**主设备访问从设备的一般过程****START和STOP条件**数据有效性和字节格式确认(ACK)和不确认(NACK)IIC 数据传输向从器件写入数据从从机读取数据AT24C02芯片(EEPROM)程序设计…

TCP报文的交互过程

TCP建立连接和断开连接的过程如下图所示,在TCP 协议提供可靠的连接服务时,采用三次握手建立一个连接,采用四次握手来关闭一个连接。 建立TCP连接的三次握手: 第一次握手:建立连接时,客户端发送 SYN 包到服务…

【FLEXPART】拉格朗日粒子扩散模式

拉格朗日粒子扩散模式FLEXPART通过计算点、线、面或体积源释放的大量粒子的轨迹,来描述示踪物在大气中长距离、中尺度的传输、扩散、干湿沉降和辐射衰减等过程。该模式既可以通过时间的前向运算来模拟示踪物由源区向周围的扩散,也可以通过后向运算来确定…

2023-Python实现有道翻译接口加密解密

文章目录👉1、目标网址👉2、寻找翻译结果接口并分析👉3、Python 实现有道翻译接口调用👉4、最理想的接口分析👉5、最终实现的密文解密学习记录:2023–有道翻译接口 sign 等参数的加密 及 返回的密文数据解…

Unity组件——LayoutElement (UI自动布局组件)说明

声明:本文为个人笔记,用于学习研究使用非商用,内容为个人研究及综合整理所得,若有违规,请联系,违规必改。 LayoutElement (UI自动布局组件)说明 文章目录LayoutElement (UI自动布局组件)说明一.开发环境二.…

Springmvc程序

1. IDEA创建maven项目 2.pom.xml中导入依赖&#xff08;依赖从maven Repository中可查找&#xff09; maven Repository https://mvnrepository.com/ <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId…

Unity Animation -- 导入动画

尽管Unity中的动画工具已经比较强大了&#xff0c;但对于非常复杂的或很长的动画&#xff0c;通常是由外部DCC创建。特别是对于角色动画来说&#xff0c;需要在动画过程中进行复杂的控制。因此我们通常需要将外部制作的动画导入到Unity中。 动画能被共享吗 对于复杂的动画&…

Java阶段一Day15

Java阶段一Day15 文章目录Java阶段一Day15集合及相关接口Collection的常用方法集合的遍历及新循环集合中的泛型集合和数组转换教师总结回顾&#xff1a;精华笔记&#xff1a;笔记&#xff1a;补充&#xff1a;集合及相关接口 什么是集合&#xff1a;和数组一样可以保存一组数据…

SuperMap GIS基础产品三维GIS FAQ集锦(1)

SuperMap GIS基础产品三维GIS FAQ集锦&#xff08;1&#xff09; 【WebGL】交通仿真示例代码中&#xff0c;动态图层中加载带有透明度的S3M模型&#xff0c;遮挡了其他不带有透明度的S3M模型&#xff0c;怎么办&#xff1f; 【问题原因】加载url模型信息时&#xff0c;如带有…
最新文章