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

devtools/2024/12/28 2:26:17/

设计模式的分类

我们都知道有 23 种设计模式,这 23 种设计模式可分为如下三类:

  • 创建型模式(5 种):单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。
  • 结构型模式(7 种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
  • 行为型模式(11 种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

在这里插入图片描述

设计模式系列文章传送门

设计模式的 7 大原则

设计模式–单例模式【创建型模式】

设计模式–工厂方法模式【创建型模式】

什么是抽象工厂模式

抽象工厂模式是一种创建型模式,该模式提供了一个超级工厂(抽象工厂),其他工厂来是实现这个工厂接口,同时还有一个工厂创建类,通过传入不同的参数,来创建不同的工厂,抽象工厂 模式是对工厂模式的扩展,工厂模式只是某类产品的工厂,而抽象工厂则是多类产品的工厂,可以理解为一类产品(产品族)的工厂,而抽象工厂就是工厂的工厂,是一个超级工厂。

产品族

产品族是指一类具有共同特征、相互关联的产品组合,它指的是一系列的产品,这些产品可能具有不同的规格、配置或者功能,抽象工厂模式就是对一系列产品就组成一个产品族,(工厂方法提供的一系列产品组成一个产品)。比如同样是车,我们会区分家用小汽车和货运重卡,而家用小汽车又有小米、小鹏等品牌,而活用重卡又有解放、东风等品牌,而他们又都属于车这个产品族。

抽象工厂五要素

  • 抽象工厂:定义一个接口,它声明了一组创建相关产品对象的方法,这些方法的返回值都是一个抽象产品。
  • 具体工厂:实现了抽象工厂中创建对象的方法,创建出具体的产品对象。
  • 抽象产品:定义了一个接口,声明了产品的一些方法。
  • 具体产品:定义了抽象产品下的某个具体产品,实现了抽象产品接口中的方法。
  • 工厂创造器:定义了一个静态方法,根据传入的参数类型,创建一个具体的工厂类。

案例分享

我们使用车产品模拟一个产品大类(产品族),车产品中又有家用小汽车和货用重卡,而家用小汽车又有小米、小鹏等品牌,而活用重卡又有解放、东风等品牌,我们使用这个案例来演示抽象工厂模式

小汽车接口(抽象产品)

定义小汽车接口,包含汽车创始人、型号、品牌、颜色等方法,代码如下:

public interface CompactCar {//汽车品牌String getBrand();//汽车创始人String getFounder();//汽车型号String getModel();//汽车颜色String getColor();}

定义小米汽车(具体产品)

家用小汽车有诸多品牌,我们定义一个小米汽车,代码如下:

public class XiaoMiCar implements CompactCar {@Overridepublic String getBrand() {return "小米";}@Overridepublic String getFounder() {return "雷布斯";}@Overridepublic String getModel() {return "su7";}@Overridepublic String getColor() {return "蓝色";}
}

定义小鹏汽车(具体产品)

我们再定义一个家用汽车品牌中的小鹏汽车,代码如下:

public class XiaoPengCar implements CompactCar {@Overridepublic String getBrand() {return "小鹏";}@Overridepublic String getFounder() {return "何小鹏";}@Overridepublic String getModel() {return "小鹏P7";}@Overridepublic String getColor() {return "炫酷黑";}
}

货用重卡接口(抽象产品)

货用重卡也是车中的一类,货用重卡接口包含汽车品牌、载重、颜色等方法,代码如下:

public interface BigTruck {//汽车品牌String getBrand();//汽车载重String getLoad();//汽车颜色String getColor();}

定义东风重卡汽车(具体产品)

货用重卡汽车有诸多品牌,我们定义一个东风重卡汽车,代码如下:

public class DongFengCar implements BigTruck{@Overridepublic String getBrand() {return "东风重卡";}@Overridepublic String getLoad() {return "60吨";}@Overridepublic String getColor() {return "红色";}
}

定义解放重卡汽车(具体产品)

解放重卡汽车有诸多品牌,我们定义一个解放重卡汽车,代码如下:

public class JieFangCar implements BigTruck{@Overridepublic String getBrand() {return "一汽解放重卡";}@Overridepublic String getLoad() {return "50吨";}@Overridepublic String getColor() {return "橙色";}
}

定义抽象车工厂接口(抽象工厂)

抽象车工厂接口中声明了两个方法,分别是创建家用小汽车和货用重卡。

public interface AbstractCarFactory {//生产小汽车接口CompactCar createCompactCar(String carType);//生产大货车接口BigTruck createBigTruck(String carType);}

定义小汽车工厂接口(具体工厂)

小汽车工厂实现了抽象车工厂接口,代码如下:

public class CompactCarFactory implements AbstractCarFactory {//创建小米汽车@Overridepublic CompactCar createCompactCar(String carType) {if("xiaomi".equals(carType)){return new XiaoMiCar();}else  if("xiaopeng".equals(carType)){return new XiaoPengCar();}return null;}@Overridepublic BigTruck createBigTruck(String carType) {return null;}
}

可以看到小汽车工厂也实现了货用重卡的方法,这就是抽象工厂方法的弊端,小汽车工厂根本用不到货用重卡的方法,但因为实现了抽象车工厂接口,就必须重写货用重卡的方法。

定义货用重卡工厂接口(具体工厂)

货用重卡工厂实现了抽象车工厂接口,代码如下:

public class BigTruckFactory implements AbstractCarFactory{@Overridepublic CompactCar createCompactCar(String carType) {return null;}@Overridepublic BigTruck createBigTruck(String carType) {if("dongfeng".equals(carType)){return new DongFengCar();}else if("jiefang".equals(carType)){return new JieFangCar();}return null;}
}

定义工厂创造器

定义工厂创造器可以根据我们传入的工厂类型帮我们生产具体的工厂,代码如下:

public class FactoryCreator {public static AbstractCarFactory createFactory(String factoryType) {if ("compact".equals(factoryType)) {return new CompactCarFactory();} else if ("bigtruck".equals(factoryType)) {return new BigTruckFactory();}return null;}
}

看起来工厂创造器其实是可有可无的,非必须得,看个人喜好。

测试验证

测试抽象工厂模式代码如下:

public class CarClient {public static void main(String[] args) {AbstractCarFactory compact = FactoryCreator.createFactory("compact");CompactCar xiaomi = compact.createCompactCar("xiaomi");System.out.println(xiaomi.toString());CompactCar xiaopeng = compact.createCompactCar("xiaopeng");System.out.println(xiaopeng.toString());AbstractCarFactory bigtruck = FactoryCreator.createFactory("bigtruck");BigTruck dongfeng = bigtruck.createBigTruck("dongfeng");System.out.println(dongfeng.toString());BigTruck jiefang = bigtruck.createBigTruck("jiefang");System.out.println(jiefang.toString());}}

测试执行结果如下:

com.xxx.xxx.xxx.factory.abstractfactory.XiaoMiCar@6d5380c2
com.xxx.xxx.xxx.factory.abstractfactory.XiaoPengCar@45ff54e6
com.xxx.xxx.xxx.factory.abstractfactory.DongFengCar@2328c243
com.xxx.xxx.xxx.factory.abstractfactory.JieFangCar@bebdb06

工厂模式优缺点

优点:

  • 客户端独立于具体的实现类,将产品的使用和创建分开,客户端使用工厂来穿件产品,无需关心产品的实现,隐藏了产品细节同时也有一定的解耦。
  • 增加产品容易,比如我们现在有小米和小鹏家用汽车,再增加一个蔚来汽车是很容易的。

缺点:

  • 增加新品类困难,如果想要新增一个新的品类,需要修改抽象接口代码已经下游所有代码,比如我们新增一个火车类(这里区别于新在一个品类的一个产品)。
  • 引入了抽象层,增加了系统的抽象性和理解难度,增加了代码复杂度,对于不熟悉该模式的开发人员来说,理解起来可能会有一些困难。

应用场景

  • 需要对一个产品族下的不同产品类型提供同意的访问接口,不关心某个产品的具体实现的场景。
  • 需要运行中动态的选择某种产品的场景。

总结:本篇结合理论和案例分享了抽象工厂设计模式,相比工厂方法模式,抽象工厂方法模式理解起来会更困难一点,希望不熟悉抽象工厂模式的朋友们可以静下心来分析,相信会有所帮助。

如有不正确的地方欢迎各位指出纠正。


http://www.ppmy.cn/devtools/145193.html

相关文章

leetcode hot100 搜索二维矩阵

240. 搜索二维矩阵 II 已解答 中等 相关标签 相关企业 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性: 每行的元素从左到右升序排列。每列的元素从上到下升序排列 class Solution(object): def searchMatrix(self…

Excel中index()函数

函数功能概述 INDEX 函数用于返回表格或区域中的值或对值的引用。它可以根据指定的行和列的位置从一个单元格区域中提取数据。这个函数有两种形式:数组形式和引用形式。语法结构(数组形式) INDEX(array, row_num, column_num)array&#xff0…

Hadoop、Hbase使用Snappy压缩

1. 前期准备 系统环境&#xff1a;centos7.9 配置信息&#xff1a;8C8G100G hadoop和hbase为单节点部署模式 jdk版本jdk1.8.0_361 1.1. 修改系统时间 timedatectl set-timezone <TimeZone> 1.2. 修改主机名以及主机名和IP的映射 vim /etc/hosts #将自己的主机名以及…

FTT变换Matlab代码解释及应用场景

代码解释 1. 整体结构与初始化部分 clear all;close all; clc这三条语句是 MATLAB 编程中常见的开头操作。clear all 用于清除工作区中的所有变量&#xff0c;确保后续代码运行时不会受到之前遗留变量的干扰&#xff1b;close all 会关闭所有已经打开的图形窗口&#xff0c;避…

【漏洞复现】CVE-2021-45788 SQL Injection

漏洞信息 NVD - cve-2021-45788 Time-based SQL Injection vulnerabilities were found in Metersphere v1.15.4 via the “orders” parameter. Authenticated users can control the parameters in the “order by” statement, which causing SQL injection. API: /test…

vue2+element 前端表格下载

前台下载table表格 可下载fixed columns和普通平铺的表格 exportExcel() {const tableContainer document.querySelector(#table)const fixflg tableContainer ? tableContainer.querySelector(.el-table__fixed) : null// const fixflg document.querySelector(.el-table_…

arm架构 uos操作系统离线安装k8s

目录 操作系统信息 安装文件准备 主机准备 主机配置 配置hosts&#xff08;所有节点&#xff09; 关闭防火墙、selinux、swap、dnsmasq(所有节点) 系统参数设置(所有节点) 配置ipvs功能(所有节点) 安装docker&#xff08;所有节点&#xff09; 卸载老版本 安装docke…

国自然面上项目分享|基于人工智能和病理组学的早癌筛查算法研究|基金申请·24-12-24

小罗碎碎念 今天分享的项目为【常规面上项目】&#xff0c;执行年限为2018年1月至2021年12月&#xff0c;直接费用为55万元。 今天分享的这个项目很有意思&#xff0c;因为这个项目的成果是团队2020年申报基金委优青的材料&#xff0c;并且还有临床验证和商业转化&#xff0c;值…