设计模式 之 —— 抽象工厂模式
目录
什么是抽象工厂模式?
定义
特点
抽象工厂模式(java代码示例)
首先定义第一个接口
实现第一个接口的类
定义第二个接口
实现第二个接口的类
* 创建抽象工厂类
创建扩展了 AbstractFactory 的工厂类
饮料工厂
食物工厂
* 创建一个工厂生成器类
测试类:
运行结果:
抽象工厂模式的优缺点
优点:
缺点:
总结:
什么是抽象工厂模式?
定义
抽象工厂模式(Abstract Factory Pattern),它围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。它也是一种创建型设计模式,提供了一种创建对象的最佳方式。
特点
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
抽象工厂模式提供了一种创建一系列相关或相互依赖对象的接口,而无需指定具体实现类。通过使用抽象工厂模式,可以将客户端与具体产品的创建过程解耦,使得客户端可以通过工厂接口来创建一族产品。
抽象工厂模式(java代码示例)
首先定义第一个接口
(饮料:Drinks)
public interface Drinks {void product();
}
实现第一个接口的类
(类:茶、可乐、矿泉水)
public class Tea implements Drinks {@Overridepublic void product(){System.out.println("饮料——茶");}
}
public class Cola implements Drinks {@Overridepublic void product(){System.out.println("饮料——可乐");}
}
public class MineralWater implements Drinks {@Overridepublic void product(){System.out.println("饮料——矿泉水");}
}
定义第二个接口
(食物:Foods)
public interface Foods {void product();
}
实现第二个接口的类
public class Chicken implements Foods {@Overridepublic void product(){System.out.println("食物——鸡肉");}
}
public class Beaf implements Foods {@Overridepublic void product(){System.out.println("食物——牛肉");}
}
public class Fish implements Foods {@Overridepublic void product(){System.out.println("食物——鱼肉");}
}
.......................................
( 相似地,可以继续定义n个接口,然后用类实现这些接口。)
* 创建抽象工厂类
public abstract class AbstractFactory {public abstract Drinks getDrinks(String drinks);public abstract Foods getFoods(String foods);//上边创建了多少被实现的接口,这里就可以创建多少个方法
}
(上边创建了多少被实现的接口,这里就可以创建多少个方法)
创建扩展了 AbstractFactory 的工厂类
(基于给定的信息生成实体类的对象)
饮料工厂
public class DrinksFactory extends AbstractFactory {@Overridepublic Drinks newDrinks(String DrinksType){if(DrinksType.equals(("茶"))){return new Tea();}else if(DrinksType.equals("可乐")){return new Cola();}else if(DrinksType.equals("矿泉水")){return new MineralWater();}else {System.out.println("暂时没有这种饮料");return null;}}@Overridepublic Foods newFoods(String FoodsType){return null;}
}
食物工厂
public class FoodsFactory extends AbstractFactory {@Overridepublic Drinks newDrinks(String DrinksType){return null;}@Overridepublic Foods newFoods(String FoodsType){if(FoodsType.equals(("鸡肉"))){return new Chicken();}else if(FoodsType.equals("鱼肉")){return new Fish();}else if(FoodsType.equals("牛肉")){return new Beaf();}else {System.out.println("暂时没有这种食物");return null;}}
}
(这里麻烦的是,每一个具体的工厂,没有办法只重载自己所需要的方法,都需要将 AbstractFactory 中所有的方法@Override。否则会报错,这是抽象工厂模式的缺点之一。)
* 创建一个工厂生成器类
(通过传递 “选择” 信息来获取工厂)
public class FactoryProducer {public static AbstractFactory getFactory(String choice){if(choice.equalsIgnoreCase("食物")){return new FoodsFactory();} else if(choice.equalsIgnoreCase("饮料")){return new DrinksFactory();}else {System.out.println("暂时没有该工厂");return null;}}
}
测试类:
public class Test {public static void main(String[] args) {AbstractFactory foodsFactory = FactoryProducer.getFactory("食物");AbstractFactory foodsFactory2 = FactoryProducer.getFactory("饮料");AbstractFactory foodsFactory3 = FactoryProducer.getFactory("衣服");Foods foods = foodsFactory.newFoods("鱼肉");foods.product();Foods foods2 = foodsFactory.newFoods("鸡肉");foods2.product();Foods foods3 = foodsFactory.newFoods("牛肉");foods3.product();Foods foods4 = foodsFactory.newFoods("猪肉");Drinks drinks = foodsFactory2.newDrinks("可乐");drinks.product();Drinks drinks2 = foodsFactory2.newDrinks("矿泉水");drinks.product();Drinks drinks3 = foodsFactory2.newDrinks("茶");drinks.product();Drinks drinks4 = foodsFactory2.newDrinks("啤酒");}
}
运行结果:
抽象工厂模式的优缺点
优点:
客户端独立于具体的实现类:客户端使用抽象工厂来创建产品,而不需要关心具体的实现类。这样可以降低客户端与具体实现类之间的耦合度。
易于切换产品系列:由于客户端只使用抽象工厂来创建产品,所以只需要切换具体的工厂实现类,就可以切换到不同的产品系列。
确保产品组合的一致性:每个具体工厂负责创建一个产品系列,这确保了产品之间的一致性。
支持产品等级结构:抽象工厂模式提供了一种支持产品等级结构的方式,可以很容易地增加新的产品。
缺点:
难以支持新种类的产品:如果需要添加一个新种类的产品,则需要修改抽象工厂接口以及所有的具体工厂实现。 (上述java代码 “ 创建扩展了 AbstractFactory 的工厂类 ” 中@Override)
由于引入了抽象层,增加了系统的抽象性和理解难度。对于不熟悉该模式的开发人员来说,理解工厂方法的作用和应用场景可能会有一些困难。
总结:
抽象工厂模式与工厂模式都使客户端使用抽象工厂来创建产品,而不需要关心具体的实现类。
抽象工厂模式可以很容易的增加某个种类里的新产品,但是增加新种类有些许困难(举例:在“饮料”中增加新饮品“雪碧”很简单,但在“工厂”中增加新的“甜品工厂”难)
相关文章:

设计模式 之 —— 抽象工厂模式
目录 什么是抽象工厂模式? 定义 特点 抽象工厂模式(java代码示例) 首先定义第一个接口 实现第一个接口的类 定义第二个接口 实现第二个接口的类 * 创建抽象工厂类 创建扩展了 AbstractFactory 的工厂类 饮料工厂 食物工厂 * 创建一个…...

计量经济学(十六)--一文读懂和学会医学统计学中的四种检验方法
1. 统计学是什么? 统计学是应用数学的一个分支,主要通过利用概率论建立数学模型,收集所观察系统的数据,进行量化的分析、总结,并进而进行推断和预测,为相关决策提供依据和参考。它被广泛的应用在各门学科之上,从物理和社会科学到人文科学,甚至被用来工商业及政府的情报…...

解析 C# Dictionary 代码
entries用于存储当前每个节点的数据,其中四个字段分别表示: hashCode:key对应的hash值next:处理hash冲突,可以理解为是一个链表结构,邻接表key:存储的keyvalue:存储的value bucket…...

如何利用人工智能提升工作效率
在当今这个信息爆炸的时代,我们每天都被大量的工作任务所困扰。然而,随着人工智能技术的不断发展,我们可以通过一些智能工具来提升我们的工作效率。在这篇文章中,我将分享一些关于如何利用人工智能提升工作效率的建议。 首先&…...

Linux驱动开发—Linux内核定时器概念和使用详解,实现基于定时器的字符驱动
文章目录 内核定时器概念在Linux驱动模块中使用定时器软定时器(Soft Timers)jiffies 含义高精度定时器(High Resolution Timers) 实现倒计时字符设备驱动 内核定时器概念 在 Linux 内核中,定时器是用来管理和调度延迟…...

mysql数据库:数据库,表和列的基本概念
mysql:数据库,表和列的基本概念以及导入和导出文件 数据库的概念和用途 数据库是一个有组织的数据集合,它们被存储在计算机上以便于管理和访问。数据库的主要目的是为了存储和管理数据,同时使数据能够被高效地访问、检索和更新。数…...

Nextjs 使用 graphql,并且接入多个节点
写在前面 随着区块链技术的流行,也促进了 subgraph 工具的兴起。那么如何在前端接入 graphql 节点就成了关键,其接入方式既存在与 restful 接口相类似的方式,也有其独特接入风格。本文将介绍如何接入 graphql 以及如何应对多个 graphql 节点…...

小结——知识注入
所谓知识注入,其实不该脱离于LLM的基础工作原理,然后空谈抽象概念。 知识,也就是你问他问题,他能输出正确的回答,这只是一个简单的输出token的过程。输出得准了,就是知识,输出不准了,…...

科普文:微服务之Spring Cloud Alibaba组件Nacos一致性协议Distro+Raft概叙
一、概要 Nacos是阿里开放的一款中间件,它主要提供三种功能:持久化节点注册,非持久化节点注册和配置管理。 二、一致性协议 - AP/CP Nacos不是纯粹的AP服务,也不是纯粹的CP服务,而是两者同时支持。 这要从服务注册…...

python合并音视频-通过ffmpeg合并音视频
🌈所属专栏:【python】✨作者主页: Mr.Zwq✔️个人简介:一个正在努力学技术的Python领域创作者,擅长爬虫,逆向,全栈方向,专注基础和实战分享,欢迎咨询! 您的…...

Yolov8添加ConvNetV1和V2模块
Yolov8添加ConvNet模块 1 ConvNet系列相关内容 (1)2022 论文地址:A ConvNet for the 2020s Code Link 如下图所示,精度、效率、尺寸都很不错。 论文的摘要如下: 视觉识别的“咆哮的 20 年代”始于视觉注意力 &…...

十个常见的 Python 脚本 (详细介绍 + 代码举例)
1. 批量重命名文件 介绍: 该脚本用于批量重命名指定目录下的文件,例如将所有 ".txt" 文件重命名为 ".md" 文件。 import osdef batch_rename(directory, old_ext, new_ext):"""批量重命名文件扩展名。Args:directory: 要处理…...

【C语言】详解feof函数和ferror函数
文章目录 前言1. feof1.1 feof函数原型1.2 正确利用函数特性读写文件1.2.1 针对文本文件1.2.2 针对二进制文件 1.3 feof函数的原理1.4 feof函数实例演示 2. ferror2.1 ferror函数原型 前言 或许我们曾在网络上看过有关于feof函数,都说这个函数是检查文件是否已经读…...

ValueListenableBuilder 和 addListener 在 ChangeNotifier的区别
1、前言 ValueListenableBuilder 和 addListener 在 ChangeNotifier 中有不同的用途和用法,适用于不同的场景。它们的主要区别在于它们如何监听和响应状态变化,以及它们的用法和特性。 2、ValueListenableBuilder用法 ValueListenableBuilder 是一个 …...

ScriptEcho:AI赋能的前端代码生成神器
ScriptEcho:AI赋能的前端代码生成神器 在前端开发中,如果你总是觉得写代码太费时费力,那么 ScriptEcho 将成为你的救星。这个 AI 代码生成平台不仅能帮你省下大量时间,还能让你轻松愉快地写出生产级代码。本文将带你了解 ScriptEc…...

TypeError: ‘float’ object is not iterable 深度解析
TypeError: ‘float’ object is not iterable 深度解析与实战指南 在Python编程中,TypeError: float object is not iterable是一个常见的错误,通常发生在尝试对浮点数(float)进行迭代操作时。这个错误表明代码中存在类型使用不…...

灵茶八题 - 子序列 +w+
灵茶八题 - 子序列 w 题目描述 给你一个长为 n n n 的数组 a a a,输出它的所有非空子序列的元素和的元素和。 例如 a [ 1 , 2 , 3 ] a[1,2,3] a[1,2,3] 有七个非空子序列 [ 1 ] , [ 2 ] , [ 3 ] , [ 1 , 2 ] , [ 1 , 3 ] , [ 2 , 3 ] , [ 1 , 2 , 3 ] [1],[…...

为什么美元债务会越来越多?
美元债务规模持续膨胀,其背后原因复杂多样,可归结为以下几个主要因素: 财政赤字和刺激政策是导致美元债务增加的重要原因。美国政府长期面临财政赤字问题,支出远超收入,为弥补这一缺口,政府不得不大量发行…...

二维凸包算法 Julia实现
问题描述:给定平面上 n n n 个点的集合 Q Q Q,求其子集 P P P 构成 Q Q Q 的凸包,即 ∀ p ∈ Q , ∃ p 0 , p 1 , p 2 ∈ P \forall p \in Q, \exist p_0, p_1, p_2 \in P ∀p∈Q,∃p0,p1,p2∈P 使得点 p p p 在以点 p 0 , p 1 …...

python dash框架
Dash 是一个用于创建数据分析型 web 应用的 Python 框架。它由 Plotly 团队开发,并且可以用来构建交互式的 web 应用程序,这些应用能够包含图表、表格、地图等多种数据可视化组件。 Dash 的特点: 易于使用:Dash 使用 Python 语法…...

2.外部中断(EXTI)
理论 NVIC:嵌套向量中断控制器(解释教程) 外部通用中断线(EXTI0~EXTI15):每个GPIO设置成中断模式,与中断控制器连接的线 外部中断触发方式 上升沿触发、下降沿触发、双边沿触发 外部中断触发函数 在stm32f1xx_it.c文件…...

Python | SyntaxError: invalid syntax 深度解析
Python | SyntaxError: invalid syntax 深度解析 在Python编程中,SyntaxError: invalid syntax是一个常见的错误,它表明Python解释器在尝试解析代码时遇到了语法问题。这个错误通常是由于代码中存在拼写错误、缺少符号(如括号、冒号或逗号&a…...

付费进群系统源码原版最新修复全开源版
付费进群,和平时所见到的别人拉你进群是不一样的,付费进群需要先缴费以后,才会看到群的二维码,扫码进群或者是长按二维码图片识别进群,付费进群这个功能广泛应用于拼多多的砍价群,活动的助力群,…...

Docker容器部署的SpringBoot项目jar包,上传文件但是找不到路径的问题
在docker容器内部署的jar包运行后,请求访问都没有问题,在文件上传时,发现上传图片接口响应成功,但是图片路径报404错误,发现找不到路径。 在服务器上查看也没有找到相关图片。 原因: 启动docker镜像时没…...

云计算学习——5G网络技术
系列文章目录 提示:仅用于个人学习,进行查漏补缺使用。 Day1 网络参考模型 Day2 网络综合布线与应用 Day3 IP地址 Day4 华为eNSP网络设备模拟器的基础安装及简单使用 Day5 交换机的基本原理与配置 Day6 路由器的原理与配置 Day7 网络层协议介绍一 Day8 传…...

matlab仿真 信道编码和交织(上)
(内容源自详解MATLAB/SIMULINK 通信系统建模与仿真 刘学勇编著第八章内容,有兴趣的读者请阅读原书) clear all N10;%信息比特的行数 n7;%hamming码组长度n2^m-1 m3;%监督位长度 [H,G]hammgen(m);%产生(n,n-…...

基于YOLOv8的高压输电线路异物检测系统
基于YOLOv8的高压输电线路异物检测系统 (价格88) 包含 【“鸟窝”,“风筝”,“气球”,“垃圾”】 4个类 通过PYQT构建UI界面,包含图片检测,视频检测,摄像头实时检测。 (该系统可以根据数…...

23款奔驰GLS450加装原厂电吸门配置,提升车辆舒适性和便利性
今天是一台22款奔驰GLS450,车主是佛山的 以前被不良商家坑了 装了副厂的电吸门 刚开始就很正常 用了半年之后 就开始开不了门,被锁在里面,刚开始车主以为是零件坏了 后来越来越频繁,本来是为了家里老人小孩关门方便而升级的&#…...

git操作流程笔记
1、在本地项目文件夹右击鼠标点击Git Bash Here 2、输入git init,这个目录变成git可以管理的仓库,会出现一个.git文件夹,如果没出现的话需要选择“显示隐藏文件”(不会的同学自行百度一下) 3、绑定本地仓库与远程仓库…...

【QT】常用控件-上
欢迎来到Cefler的博客😁 🕌博客主页:折纸花满衣 目录 👉🏻QWidgetenabledgeometryrect制作上下左右按钮 window frame 的影响window titlewindowIcon代码示例: 通过 qrc 管理图片作为图标 windowOpacitycursor使用qrc自…...

怎么用电脑给域名做网站/推送者seo
我全局安装的cnpm 一直找不到 cnpm 就想起来之前看的一篇博客 想着重新设置下 看可不可以 就修复好了。 https://www.kancloud.cn/han88829/book/1097164 原文地址 应该是npm 的环境变量出了问题。需要重新更新设置下。应该就可以了 查看npm 默认安装路径 npm config get pre…...

1000学习做网站贵吗/观看b站的广告网站平台
2019独角兽企业重金招聘Python工程师标准>>> binSort.cpp /** 这里是主函数的执行文件 * binSort.cpp */ #include<iostream> #include"studentrecord1.h" #include"chainwithiterator.h" #include"myexceptions.h"void…...

工程建设官方网站/百度应用
Solr介绍Solr 是基于Lucene的面向企业搜索的web应用Solr 采用Java开发,是一个独立的高性能的企业级搜索应用服务器,它对外提供类似于Web-service的API接口,用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件࿰…...

wordpress作者认证/信息流优化师是什么
商业计划书撰写指南 (本文《商业计划书撰写指南》转载自搜狐理财频道:http://money.sohu.com) 商业计划书撰写指南 商业计划书, 商业计划书撰写指南实战 在融资过程中,创业者如何与风险投资者接触并建立良好的合…...

做美食视频的网站/南昌seo建站
Linux下chmod命令用得很多,但是有时会忘记此命令的正确用法和一些注意事项。最近用得比较多,总结一下。 chmod命令用途 用于改变Linux系统的文件的访问权限。通常用它来控制文件的访问权限,使文件可写或者使文件只允许某些用户进入。 ##Linux…...

wordpress 栏目投稿/优化推广网站淄博
首先PHP语言是一种面向对象的语言而C语言是面向过程的。PHP主要是用来开发web程序的语言,而C语言是种广泛使用的语言,尤其用来书写一下比较复杂的后台代码。 PHP和C语言一样,有着if, else, elseif ,switch, while, do-while, for, break, con…...