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

文章目录

  • 一、抽象工厂模式
    • 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();// 生产海尔品牌的空调
        }
    }
    

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

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

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

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

使用场景:

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

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

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

相关文章

泡泡玛特“失速”,盲盒经济迎来拐点?

配图来自Canva可画​ 前些年泡泡玛特的飞速增长,曾经在行业内外引起了广泛的反响,其主打的盲盒经济也曾风靡一时、被众多行业效仿。不过,这种情况在疫情肆虐的2022年似乎受到了一些影响,这在其财报中就有所体现。 3月29日&#…

Python 小型项目大全 61~65

六十一、ROT13 密码 原文:http://inventwithpython.com/bigbookpython/project61.html ROT13 密码是最简单的加密算法之一,代表“旋转 13 个空格”密码将字母A到Z表示为数字 0 到 25,加密后的字母距离明文字母 13 个空格: A变成N&…

【Android】之【自定义View实践】

这里以一个进度条的加载为例子&#xff0c;先看效果&#xff08;运行效果是动态变化的&#xff09; 一、自定义属性 首先在res->values目录下新建attrs资源文件&#xff0c;如下图&#xff1a; 内容如下&#xff1a; <?xml version"1.0" encoding"utf…

SpringBoot基础学习之(九)添加员工的信息

本次项目所有能够使用的静态资源可以免费进行下载 静态资源 在本篇代码DAO层将通过Java文件去实现&#xff0c;在这里就不连接数据&#xff0c;然后通过jdbc将数据库内容的内容显示出来 案例&#xff1a;员工管理系统 上一篇博文的主要的内容是展示员工的信息&#xff0c;本篇…

Oracle JDK 和 OpenJDK 有什么区别?

可能在看这个问题之前很多人和我一样并没有接触和使用过 OpenJDK 。那么 Oracle JDK 和 OpenJDK 之间是否存在重大差异&#xff1f;下面我通过收集到的一些资料&#xff0c;为你解答这个被很多人忽视的问题。 首先&#xff0c;2006 年 SUN 公司将 Java 开源&#xff0c;也就有…

JAVA——网络编程基本概念

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点!人生格言&#xff1a;当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔&#x1f9be;&am…

腾讯云轻量服务器和云服务器区别对比(超详细)

腾讯云轻量服务器和云服务器有什么区别&#xff1f;为什么轻量应用服务器费用更低&#xff1f;是因为轻量服务器CPU内存性能比云服务器CVM性能差吗&#xff1f;轻量应用服务器适合中小企业或个人开发者搭建企业官网、博客论坛、微信小程序或开发测试环境&#xff0c;云服务器CV…

orcad library builder 建库及报错问题

目录 一.安装orcad library builder 二.orcad library builder 使用 1.建立一个orcad 原理图库测试下 尝试理解tcl那段的意思 xml文件导入建orcad库 折腾了2个多小时&#xff0c;居然没有直接方案搞定&#xff0c;简单记录下&#xff0c;后面遇到该问题的兄弟可参考借鉴&am…

Java集合框架之collection

1. 什么是集合 1.1 概念 对象的容器&#xff0c;实现类对对象常用的操作。 1.2 和数组的区别 数组长度固定&#xff0c;集合长度不固定。数组可以存储基本类型和引用类型&#xff0c;集合只能存储引用类型。 1.3 位置 java.util.*; 2. Collection体系 2.1 Collection父接…

网络编程 1

前言 小亭子正在努力的学习编程&#xff0c;接下来将开启javaEE的学习~~ 分享的文章都是学习的笔记和感悟&#xff0c;如有不妥之处希望大佬们批评指正~~ 同时如果本文对你有帮助的话&#xff0c;烦请点赞关注支持一波, 感激不尽~~ 目录 网络编程 什么是网络编程&#xff1f;…

ASP网上视频点播系统的设计与实现

在线视频服务系统的功能模块划分如下图&#xff08;2-2&#xff09;所示&#xff1a; 电影分类浏览 用户可以通过电影的类别进行浏览。显示近期热门电影&#xff0c;近期点机排行。用户能很方便的找到自己感兴趣的电影进行观看。 电影搜索 如果用户有很明确的目的&#xff0c;…

JUC结构

JUC是java.util.concurrent包的简称在Java5.0添加&#xff0c;目的就是为了更好的支持高并发任务。让开发者进行多线程编程时减少竞争条件和死锁的问题&#xff01;进程与线程的区别&#xff1a;进程 : 一个运行中的程序的集合; 一个进程往往可以包含多个线程,至少包含一个线程…

JVM的内存区域划分

目录 1、程序计数器&#xff08;内存中最小的一块&#xff0c;里面保存了当前线程下一条执行的指令的地址&#xff09; 2、栈&#xff08;保存局部变量和方法调用的信息&#xff09; 3、堆 &#xff08;成员变量和new出来的对象都在堆上&#xff09; 4、方法区&#xff08…

闲人闲谈PS之四十——项目售前费用归集

惯例闲话&#xff1a;广东这段时间老是下雨&#xff0c;堪比江浙一带梅雨季节&#xff0c;人的心情也像这天气一样&#xff0c;阴雨绵绵。2023年伊始&#xff0c;确实感觉很多事情在发生剧变&#xff0c;这种变化也稍微影响了闲人那本来稳如老狗的心。面对未知和变化&#xff0…

FreeRTOS学习(一)

裸机与RTOS对比 裸机&#xff1a;又称为前后台系统&#xff0c;前台系统指的是中断服务函数&#xff0c;后台系统指的大循环&#xff0c;即应用程序。 实时性差&#xff1a;&#xff08;应用程序轮流执行&#xff09;delay&#xff1a;空等待&#xff0c;CPU不执行其它代码结…

智能汽车赛道「年度大奖」揭晓,哪些供应商在细分市场独占鳌头

智能汽车产业链年度细分市场领军供应商&#xff0c;是高工智能汽车研究院在每个年度基于前装量产数据库及定点车型库数据进行综合评价颁发的年度重量级行业奖项。 2022年&#xff0c;是中国乘用车市场从电动化转型升级到全面普及智能化的关键节点。从计算平台、域控制器、传感…

python天狗吃月 青少年编程电子学会python编程等级考试一级真题解析2022年9月

目录 python天狗吃月 一、题目要求 编程实现 二、解题思路 1、图形分析

thinkphp5.0无限极分类及格式化输出详解案例一则

首先我们来看数据表 从上图中可以发现&#xff0c;中国下有贵州&#xff0c;北京两个子节点&#xff0c;而北京有天安门一个子节点&#xff0c;纽约的子节点是“纽约的子类”。 从pid为0看出&#xff0c;中国和纽约是顶级节点。 因为贵州的pid是1&#xff0c;而中国的id为1…

概率论基础2

文章目录多个random variable条件下的multi random variable 分布和independencemulti random variable continuous**2D normal distribution**two random variable independencemuilti random variable conditional expectional value(discrete)multi random variable conditi…

docker-compose 搭建 MinIO

目录1、搭建单机MinIO1、搭建单机MinIO &#xff08;1&#xff09;配置 docker-compose.yml minio: image: minio/minio container_name: "chain-minio" ports: - 9000:9000 # 服务端口 - 9090:9090 # 控制台端口 environment: - "MINIO_ACCESS_KEYadmin"…