当前位置: 首页 > news >正文

抽象工厂模式(Abstract Factory Pattern)

1.抽象工厂模式定义:

抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口,无需指定它们具体的类

2.抽象工厂模式适用场景:

  • 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
  • 强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量的重复代码
  • 提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现

3.抽象工厂模式的优缺点:


优点:

  • 具体产品在应用层的代码隔离,无需关心创建的细节
  • 将一个系列的产品统一到一起创建


缺点:

  • 规定了所有可能被创建的产品集合,产品簇中扩展新的产品困难
  • 增加了系统的抽象性和理解难度

创建一个手机接口 cn.xs.abstraction.IPhoneProduct
代码如下:
public interface IPhoneProduct {
/**
* 开机
*/
void open();
/**
* 关机
*/
void close();
/**
* 发短信
*/
void send();
/**
* 打电话
*/
void call();
}
创建一个路由器接口 cn.xs.abstraction.IRouterProduct
代码如下:
public interface IRouterProduct {
/**
* 开机
*/
void open();
/**
* 关机
*/
void close();
/**
* 设置参数
*/
void setting();
/**
* 打开 wifi
*/
void wifi();
}
新建小米手机产品类 cn.xs.abstraction.XiaomiPhone
代码如下:
public class XiaomiPhone implements IPhoneProduct {
public void open() {
System.out.println("小米手机开机");
}
public void close() {
System.out.println("小米手机关机");
}
public void send() {
System.out.println("小米手机发短信");
}
public void call() {
System.out.println("小米手机打电话");
}
}
新建小米路由器产品类 cn.xs.abstraction.XiaomiRouter
 
代码如下:
public class XiaomiRouter implements IRouterProduct {
public void open() {
System.out.println("小米路由器开机");
}
public void close() {
System.out.println("小米路由器关机");
}
public void setting() {
System.out.println("小米路由器设置参数");
}
public void wifi() {
System.out.println("小米路由器打开wifi");
}
}
新建华为手机产品类 cn.xs.abstraction.HuaweiPhone
代码如下:
public class HuaweiPhone implements IPhoneProduct {
public void open() {
System.out.println("华为手机开机");
}
public void close() {
System.out.println("华为手机关机");
}
public void send() {
System.out.println("华为手机发短信");
}
public void call() {
System.out.println("华为手机打电话");
}
}
新建华为路由器产品类 cn.xs.abstraction.HuaweiRouter  
代码如下:
public class HuaweiRouter implements IRouterProduct {
public void open() {
System.out.println("华为路由器开机");
}
public void close() {
System.out.println("华为路由器关机");
}
public void setting() {
System.out.println("华为路由器设置参数");
}
public void wifi() {
System.out.println("华为路由器打开wifi");
}
}
新建抽象工厂 cn.xs.abstraction.IProductFactory 来生产手机跟路由器(抽象):
public interface IProductFactory {
/**
* 生产手机
*
* @return
*/
IPhoneProduct getPhone();
/**
* 生产路由器
*
* @return
*/
IRouterProduct getRouter();
}
新建小米工厂 cn.xs.abstraction.XiaomiFactory 来生产手机跟路由器:
public class XiaomiFactory implements IProductFactory {
public IPhoneProduct getPhone() {
return new XiaomiPhone();
}
public IRouterProduct getRouter() {
return new XiaomiRouter();
}
}
新建华为工厂 cn.xs.abstraction.HuaweiFactory 来生产手机跟路由器:

 

public class HuaweiFactory implements IProductFactory {
public IPhoneProduct getPhone() {
return new HuaweiPhone();
}
public IRouterProduct getRouter() {
return new HuaweiRouter();
}
}

 根据类图关系深入了解:

 

新建测试类 cn.xs.abstraction.Client 来进行测试:

public class Client {
/**
* 测试方法
*
* @param args
*/
public static void main(String[] args) {
System.out.println("==========小米系列产品==========");
// 创建小米工厂
IProductFactory factory1 = new XiaomiFactory();
IPhoneProduct phone1 = factory1.getPhone();
phone1.send();
phone1.call();
IRouterProduct router1 = factory1.getRouter();
router1.setting();
router1.wifi();
System.out.println("==========华为系列产品==========");
// 创建华为工厂
IProductFactory factory2 = new HuaweiFactory();
IPhoneProduct phone2 = factory2.getPhone();
phone2.send();
phone2.call();
IRouterProduct router2 = factory2.getRouter();
router2.setting();
router2.wifi();
}
}

再看一下整体的一个类图

运行 main  

抽象工厂模式在产品稳定的情况下是极其强大的,但是如果要添加产品,其子类都需要修改代码,违反了开闭原则
小结:
简单工厂模式(静态工厂模式):

虽然某种程度上不符合设计原则,但实际使用最多!
工厂方法模式:

不修改已有类的前提下,通过增加新的工厂类实现扩展
抽象工厂模式:

不可以增加产品,可以增加产品族!

应用场景:

JDK中Calendar的getInstance方法
JDBC中的Connection对象的获取
Spring中IOC容器创建管理bean对象反射中Class对象的newInstance方法

 

相关文章:

抽象工厂模式(Abstract Factory Pattern)

1.抽象工厂模式定义: 抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口,无需指定它们具体的类 2.抽象工厂模式适用场景: 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量…...

Linux驱动学习笔记

驱动学习笔记 1、字符设备驱动 Linux 驱动有两种运行方式 第一种就是将驱动编译进 Linux 内核中,这样当 Linux 内核启 动的时候就会自动运行驱动程序。 第二种就是将驱动编译成模块(Linux 下模块扩展名为.ko),在 Linux 内核启动以后使用“insmod”命…...

tarfile — 访问 Tar 压缩文件

tarfile — 访问 Tar 压缩文件 1.概述 tarfile 模块提供对 Unix tar 存档的读写访问,包括压缩文件。除了 POSIX 标准之外,还支持几种 GNU tar 扩展。还提供处理 Unix 特殊文件类型,如硬链接和软链接,以及设备节点. 虽然 tarfile…...

C++14深度探索之C++基础-共享指针与弱指针使用

shared_ptr : 共享指针 管理多个客户使用的内存,多客户都拥有该内存块, 当共享指针不再拥有该内存时,内存会自动释放, 多用于并发领域,当所有访问该内存的线程都退出时,释放该内存 共享指针可被随意复制,与独占指针相反,独占指针不能被复制 在内存与时间上有一定的开销…...

【React全家桶】reac组件通信

🎞️🎞️🎞️ 博主主页: 糖 -O- 👉👉👉 react专栏:react全家桶 🌹🌹🌹希望各位博主多多支持!!&a…...

2023,再转行去做软件测试还有前途吗?

近年来,以云计算、移动互联网、物联网、工业互联网、人工智能、大数据及区块链等新一代信息技术构建的智能化应用和产品出现爆发式增长,突破了传统对于软件形态的认知,软件形态正以各种展现方式诠释着对新型智能软件的定义。这也使得软件的质…...

Java程序API数据接口

API:应用程序接口(API:Application Program Interface) 一、使用数据接口的作用 1、封装逻辑 数据接口从数据库查询出数据,并组织成json格式,这个逻辑如果在每个终端都写一遍,那样将编写大量…...

剑指offer 7 数组中和为0的三个数

此问题属于nsum问题,题目链接:力扣 要求在数组中找到不重复的三元组,三个数加起来为0,且每个下标只能用一次。而且需要返回所有这样的不重复数组。 1. 排序 双指针 1. 「不重复」的本质是什么?我们保持三重循环的大…...

DockerFile

大家想想,Nginx,tomcat,mysql 这些镜像都是哪里来的?官方能写,我们不能写吗? 我们要研究自己如何做一个镜像,而且我们写的微服务项目以及springboot打包上云部署,Docker就是最方便的…...

Vue-Router 介绍及路由原理分析

文章目录Vue-Router 路由模式单页面与传统页面跳转的区别Hash 模式History 模式abstract 模式原理解析Hash 模式原理History 模式原理路由使用引入 Vue-Router获取全局路由跳转参数的变化获取路由中带的参数重定向页面Vue-Router 路由模式 单页面与传统页面跳转的区别 单页面…...

git代码提交后jenkins构建和自动部署

利用jenkins和gitlab的webhook结合,实现提交代码之后,自动触发jenkins的构建。顺带介绍一下通过触发器构建,比如直接通过url去触发的方式。 一、jenkins结合webhook 1、jenkins配置 a、首先jenkins得需要安装两个gitlab的插件:(…...

2023面试题目总结

项目遇到的问题难点? 老项目版本过低(angular4),相关框架太少,需要升级成新框架。 1.single-spa 2.qiankun 3.iframe 样式环境隔离/js隔离/公共依赖的加载 JS 原型,原型链,new 原型是存放公共属性地方,所有实例都…...

Vue常用指令及声明周期

文章目录知识点前端开发环境配置v-text && v-htmlv-if、v-else && v-showv-forv-onv-modelv-bind、v-cloak、v-pre&&v-once全局 API 是什么Vue.directive 自定义组件Vue.directive 是什么自定义组件回调函数参数自定义组件的生命周期Vue.set 全局操作为…...

MariaDB 成功敲钟上市 | 它与 Navciat 缘起 10 年前

MariaDB 敲钟上市2022 年底,云数据库公司 MariaDB 与 Angel Pond Holdings 公司完成合并,并在纽交所上市。新公司更名为 MariaDB,MySQL 之父奋斗了13年终敲钟。这标志着 MariaDB 开启新篇章。无论从开源还是商业之路,都将成为业内…...

LESS模型与随机森林

模型学习 1 随机森林 https://blog.csdn.net/weixin_35770067/article/details/107346591? 森林就是建立了很多决策树,把很多决策树组合到一起就是森林。 这些决策树都是为了解决同一任务建立的,最终的目标也都是一致的,最后将其结果来平均…...

如何利用Power Virtual Agents机器人实现成绩查询服务

今天我们继续介绍如何利用Power Virtual Agents来实现成绩查询服务。设计思路是在PVA聊天机器人的对话框中输入学生的姓名和学号来进行成绩的查询。首先,在Microsoft 365的OneDrive中制作一个Excel格式的成绩单。 可以将学生的学号、姓名、各学科成绩进行添加。 在P…...

flavor 配置

文章目录1. flavorDimensions1.1 单维度1.2 多维度2. BuildConfig3. sourceSets4. 参考资料1. flavorDimensions 与 productFlavors 配合使用使用 flavorDimensions 定义风味维度,维度越多,能打出的渠道包越丰富 1.1 单维度 defaultConfig {...flavor…...

《第一行代码》 第五章:详解广播机制

如果你了解网络通信原理应该会知道,在一个 IP 网络范围中最大的IP 地址是被保留作为广播地址来使用的。比如某个网络的 IP 范围是 192.168.0XXX,子网掩码是255.255.255.0那么这个网络的广播地址就是 192.168.0255广播数据包会被发送到同-网络上的所有端口…...

Leetcode(每日一题)——1139. 最大的以 1 为边界的正方形

摘要 1139. 最大的以 1 为边界的正方形 一、以1为边界的最大正方形 1.1 动态规划 第530题需要正方形所有网格中的数字都是1,只要搞懂动态规划的原理,代码就非常简洁。而这题只要正方形4条边的网格都是1即可,中间是什么数字不用管。 这题…...

YOLOv5:GitHub两万八Star项目

来源:投稿 作者:王同学 编辑:学姐 Yolov5详解 官方源码仓库:https://github.com/ultralytics/yolov5 相关论文:未发表(改进点都被你们抢先发了) 0 前言 截止到2022年7月,Yolov5项…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...