设计模式(十):抽象工厂模式(创建型模式)

        Abstract Factory,抽象工厂:提供一个创建一系列相关或相互依赖对
象的接口,而无须指定它们的具体类。

       之前写过简单工厂和工厂方法模式(创建型模式),这两种模式比较简单。

       简单工厂模式其实不符合开闭原则,即对修改关闭,扩展开放。简单工厂每次需要新增新的产品就需要修改工厂类。而工厂方法模式,每个工厂只负责创建单一的产品,相当于真实工厂里面的一条流水线,如果一个工厂自身能创建多个产品呢?那就需要抽象工厂了。

      三种工厂模式的区别:

      简单工厂模式:一个抽象产品类(或接口),可以派生出多个具体产品类。 
                               只有一个静态工厂,负责创建多个具体产品类的实例。
      工厂方法模式:一个抽象产品类(或接口),可以派生出多个具体产品类。   
                               一个抽象工厂类(或接口),可以派生出多个具体工厂类。   
                               每个具体工厂类只能创建一个具体产品类的实例。  
      抽象工厂模式:多个抽象产品类(或接口),可以派生出多个具体产品类。   
                               一个抽象工厂类(或接口),可以派生出多个具体工厂类。   
                               每个具体工厂类可以创建多个具体产品类的实例。   
   
区别:工厂方法模式只有一个抽象产品类(或接口),而抽象工厂模式有多个。   
      工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。


“抽象工厂”就像真的工厂,“工厂方法”就像工厂中的一条生产线。

抽象工厂模式Demo:

先看类图:

工程结构:

上代码:

package com.figo.study2024.pattern.abstractfactory;/*** @ClassName:Fruit* @PackageName:com.figo.study2024.pattern.abstractfactory* @Description:水果接口* @Date:2024/3/8 10:25* @Author:figo*/
public interface Fruit {//采摘void pick();
}package com.figo.study2024.pattern.abstractfactory;/*** @ClassName:Apple* @PackageName:com.figo.study2024.pattern.abstractfactory* @Description:苹果产品* @Date:2024/3/8 10:32* @Author:figo*/
public class Apple implements Fruit{@Overridepublic void pick() {System.out.println("采摘苹果");}
}package com.figo.study2024.pattern.abstractfactory;/*** @ClassName:Banana* @PackageName:com.figo.study2024.pattern.abstractfactory* @Description:香蕉产品* @Date:2024/3/8 10:35* @Author:figo*/
public class Banana implements Fruit{@Overridepublic void pick() {System.out.println("采摘香蕉");}
}package com.figo.study2024.pattern.abstractfactory;/*** @ClassName:Bag* @PackageName:com.figo.study2024.pattern.abstractfactory* @Description:包装盒接口* @Date:2024/3/8 10:36* @Author:figo*/
public interface Bag {//打包void pack(Fruit fruit);
}package com.figo.study2024.pattern.abstractfactory;/*** @ClassName:AppleBag* @PackageName:com.figo.study2024.pattern.abstractfactory* @Description:苹果包装盒* @Date:2024/3/8 10:37* @Author:figo*/
public class AppleBag implements Bag{@Overridepublic void pack(Fruit fruit) {System.out.println("苹果盒打包苹果");}
}package com.figo.study2024.pattern.abstractfactory;/*** @ClassName:BananaBag* @PackageName:com.figo.study2024.pattern.abstractfactory* @Description:香蕉包装盒* @Date:2024/3/8 10:37* @Author:figo*/
public class BananaBag implements Bag{@Overridepublic void pack(Fruit fruit) {System.out.println("香蕉盒打包苹果");}
}package com.figo.study2024.pattern.abstractfactory;/*** @ClassName:AbstractFactory* @PackageName:com.figo.study2024.pattern.abstractfactory* @Description:抽象工厂,能生产多种产品,比工厂方法模式只能生产单一产品更强* @Date:2024/3/8 10:42* @Author:figo*/
public abstract class AbstractFactory {public abstract  Fruit getFruit();public abstract Bag getBag();
}package com.figo.study2024.pattern.abstractfactory;/*** @ClassName:AppleFactory* @PackageName:com.figo.study2024.pattern.abstractfactory* @Description:苹果工厂能生产苹果和苹果包装盒* @Date:2024/3/8 10:46* @Author:figo*/
public class AppleFactory extends AbstractFactory{@Overridepublic Fruit getFruit() {return new Apple();}@Overridepublic Bag getBag() {return new AppleBag();}
}package com.figo.study2024.pattern.abstractfactory;/*** @ClassName:BananaFactory* @PackageName:com.figo.study2024.pattern.abstractfactory* @Description:香蕉工厂,能生产香蕉也能生产香蕉包装盒* @Date:2024/3/8 10:49* @Author:figo*/
public class BananaFactory extends AbstractFactory{@Overridepublic Fruit getFruit() {return new Banana();}@Overridepublic Bag getBag() {return new BananaBag();}
}package com.figo.study2024.pattern.abstractfactory;/*** @ClassName:FruitGardenClient* @PackageName:com.figo.study2024.pattern.abstractfactory* @Description:水果园客户端,测试抽象工厂模式* @Date:2024/3/8 10:51* @Author:figo*/
public class FruitGardenClient {public static void main(String[] args) {fruitOrder();}/*** 水果订单*/public static void fruitOrder(){//初始化工厂AbstractFactory factory = new AppleFactory();//spring使用注入方式,这里测试苹果工厂//苹果工厂能生产苹果Fruit fruit = factory.getFruit();fruit.pick();//苹果工厂也能生产包装盒Bag bag = factory.getBag();bag.pack(fruit);//以下物流运输业务。。。。}
}

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

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

相关文章

[MYSQL]当数据库被攻破如何重新恢复

前情提要:mysql数据库默认密码、默认端口没有改,也没做安全防护,导致被攻破被索要比特币。 那我们自然是不能给他们的,下面罗列我的补救方法。 密码修改相关 第一步大家自然都会想到先去修改密码: mysqladmin -u roo…

光谱下的养殖业:数据可视化的现代变革

在数字化时代,数据可视化在养殖业中崭露头角,为这一传统行业注入了新的活力。无论是家禽养殖还是水产养殖,数据可视化都以其直观、高效的特点,为养殖业带来了全新的发展机遇。下面我就以可视化从业者的角度,简单聊聊这…

腾讯云轻量 2核2G4M新用户首购活动,99续费同价来了!!

阿里云199一年续费同价,腾讯云99一年续费同价,平台卷起来,对用户的角度来说,真的是香麻了~ 腾讯云新春采购节,2核2G4兆的基础配置,新官方直接放大招,99一年,活动期间内,…

OpenAI (ChatGPT)中国免费试用地址

GitHub - click33/chatgpt---mirror-station-summary: 汇总所有 chatgpt 镜像站,免费、付费、多模态、国内外大模型汇总等等 持续更新中…… 个人能力有限,搜集到的不多,求大家多多贡献啊!众人拾柴火焰高!汇总所有 cha…

202104 CSP认证 | DHCP服务器

3. DHCP服务器 我天呢经历了带配额的文件系统我真的极其挫败,然后开始写的时候觉得这个题感觉怎么有点简单…然后就觉得肯定是自己有很多东西没有想到,而且写的时候破罐子破摔觉得肯定会超时… 结果一写!哦买噶居然满分了! 脑子不…

【探索Linux】—— 强大的命令行工具 P.26(网络编程套接字基本概念—— socket编程接口 | socket编程接口相关函数详细介绍 )

阅读导航 引言一、socket 常见API表二、函数详细介绍01. socket()02. bind()03. listen()04. accept()05. connect()06. send()07. recv()08. close()09. select()10. getaddrinfo()11. sendto()12. recvfrom()13. setsockopt()14. getsockopt()15. shutdown()16. inet_pton()1…

【SpringBoot】多环境切换的灵活配置

文章目录 profile 的使用激活 profile 的方式命令行启动idea 中配置配置文件中激活 开发中最灵活的多环境配置创建四个配置主配置文件其他几个环境配置使用方式 配置文件拆分总结 在日常的开发中,一般都会分好几种环境,比如通常的 开发环境:一…

EXSI create datastore

文章目录 1. 简介2. 清空磁盘3. 删除表4. 创建database 1. 简介 在 ESXi 环境中创建数据存储(Datastore)的步骤如下: 登录 vSphere Web Client 打开 Web 浏览器,输入 ESXi 主机或 vCenter Server 的 IP 地址,使用有权限的账户登录。 在 ESXi 环境中创建数据存储(Datastore)…

Linux 关于NTP同步硬件时钟的可靠性验证

Linux关于NTP同步硬件时钟的可靠性验证 1. 常见的时钟类型1.1 系统时钟1.2 硬件时钟 2. 常见时钟同步方式2.1 ntpd服务2.1.1 推荐配置/etc/ntp.conf2.1.2 推荐配置/etc/sysconfig/ntpd 2.2 定时任务ntpdate2.3 ntp命令同步状态相关命令解读2.3.1 ntpq -pn解读2.3.2 ntpdate -u解…

SpringCloud Ribbon 负载均衡服务调用

一、前言 接下来是开展一系列的 SpringCloud 的学习之旅,从传统的模块之间调用,一步步的升级为 SpringCloud 模块之间的调用,此篇文章为第三篇,即介绍 Ribbon 负载均衡服务调用 二、概述 2.1 Ribbon 是什么 Spring Cloud Ribbon…

OpenCV学习笔记(三)——对于图片的基本操作

目录 读取图片和显示图片 显示图片的大小 将图像设置为灰度图 将图片重新写回指定的地址 显示图片的尺寸 获取图片的类型 读取图片和显示图片 在OpenCV使用cv2.imread()来读取图片,例如,在D盘的Photo的文件夹中有一张图片名称为1的jpeg的图片&am…

无法使用debugger,debugger在项目中不生效,导致无法有效排查问题

debugger是浏览器提供的调试语句,其主要是通过停止JS的执行,相当于设置断点。它的使用方法很简单, 只需要在我们的JS语句中, 插入一行debugger; 即可。 在JS代码编写的过程中,我们都会通过浏览器的调试模式&#xff08…

微擎安装,卡在“安装微擎”界面

进入install.php,点击【在线安装】 下一步配置数据库,开始安装系统 然后显示进度条,进度条一闪而过 然后就没有进度条显示了,一直卡在这里 第一次等了好久, 删除目录下的文件,重装还是这样 再重启服务器&…

3D-Genome | Hi-C互作矩阵归一化指南

Hi-C 是一种基于测序的方法,用于分析全基因组染色质互作。它已广泛应用于研究各种生物学问题,如基因调控、染色质结构、基因组组装等。Hi-C 实验涉及一系列生物化学反应,可能会在输出中引入噪声。随后的数据分析也会产生影响最终输出噪声&…

Python Tkinter GUI 基本概念

归纳编程学习的感悟, 记录奋斗路上的点滴, 希望能帮到一样刻苦的你! 如有不足欢迎指正! 共同学习交流! 🌎欢迎各位→点赞 👍 收藏⭐ 留言​📝如果停止,就是低谷&#xf…

node项目通过.env文件配置环境变量

https://www.npmjs.com/package/dotenv require(dotenv).config()console.log(process.env, process.env.apiKeyOnServer)我开发的chatgpt项目: https://chat.xutongbao.top

Imagination:RISC-V CPU的重要力量

根据SHD集团最近发布的报告显示,RISC-V正全速发展中。通过分析从2021年到2030年这十年间RISC-V核在不同应用和功能领域的潜在市场,作者Rich Wawrzyniak得出结论称,到2030年,22.3%的SoC将包含RISC-V CPU,RISC-V的收入预…

Docker网络+原理+link+自定义网络

目录 一、理解Docker网络 1.1 运行tomcat容器 1.2 查看容器内部网络地址 1.3 测试连通性 二、原理 2.1 查看网卡信息 2.2 再启动一个容器测试网卡 2.3 测试tomcat01 和tomcat02是否可以ping通 2.4 只要删除容器,对应网桥一对就没了 2.5 结论 三、…

蓝牙耳机潜水时可以用吗?适合潜水的四大游泳耳机分享

在科技日新月异的今天,我们越来越依赖各种电子设备来丰富我们的生活。无论是运动、工作还是休闲娱乐,耳机都成为了我们不可或缺的伙伴之一。然而,当谈到水上活动时,许多人可能会对蓝牙耳机是否能在水下使用感到困惑。虽然市面上有…

SpringBoot第三课-日志

1.日志分类 2.默认使用 默认使用logback与slf4j作为底层默认日志 但是由于日志是系统启动就需要使用,所以与其他的自动配置不同,自动配置是后来使用的,而日志是使用监听器配置好的。 ApplicationListener 3.日志级别 1.级别介绍 SpringB…