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

工厂模式 与 抽象工厂模式 的区别

工厂模式:

// 抽象产品接口
interface Product {void showInfo();
}// 具体产品A
class ConcreteProductA implements Product {@Overridepublic void showInfo() {System.out.println("This is Product A");}
}// 具体产品B
class ConcreteProductB implements Product {@Overridepublic void showInfo() {System.out.println("This is Product B");}
}// 抽象工厂类
abstract class Creator {abstract Product createProduct();
}// 具体工厂A,生产产品A
class ConcreteCreatorA extends Creator {@OverrideProduct createProduct() {return new ConcreteProductA();}
}// 具体工厂B,生产产品B
class ConcreteCreatorB extends Creator {@OverrideProduct createProduct() {return new ConcreteProductB();}
}public class FactoryMethodExample {public static void main(String[] args) {Creator creatorA = new ConcreteCreatorA();Product productA = creatorA.createProduct();productA.showInfo();Creator creatorB = new ConcreteCreatorB();Product productB = creatorB.createProduct();productB.showInfo();}
}

在这个示例中,Product 是抽象产品接口,ConcreteProductAConcreteProductB 是具体的产品类。Creator 是抽象工厂类,ConcreteCreatorAConcreteCreatorB 是具体的工厂类,分别生产不同的产品。在场景类中,通过具体的工厂来创建不同的产品,而无需直接涉及具体产品的实现类。这就是工厂方法模式的正确用法。

抽象工厂模式:

// 抽象产品接口
interface ProductA {void showInfo();
}// 具体产品A1
class ConcreteProductA1 implements ProductA {@Overridepublic void showInfo() {System.out.println("This is Product A1");}
}// 具体产品A2
class ConcreteProductA2 implements ProductA {@Overridepublic void showInfo() {System.out.println("This is Product A2");}
}// 抽象产品接口
interface ProductB {void showInfo();
}// 具体产品B1
class ConcreteProductB1 implements ProductB {@Overridepublic void showInfo() {System.out.println("This is Product B1");}
}// 具体产品B2
class ConcreteProductB2 implements ProductB {@Overridepublic void showInfo() {System.out.println("This is Product B2");}
}// 抽象工厂接口
interface AbstractFactory {ProductA createProductA();ProductB createProductB();
}// 具体工厂1
class ConcreteFactory1 implements AbstractFactory {@Overridepublic ProductA createProductA() {return new ConcreteProductA1();}@Overridepublic ProductB createProductB() {return new ConcreteProductB1();}
}// 具体工厂2
class ConcreteFactory2 implements AbstractFactory {@Overridepublic ProductA createProductA() {return new ConcreteProductA2();}@Overridepublic ProductB createProductB() {return new ConcreteProductB2();}
}public class AbstractFactoryExample {public static void main(String[] args) {AbstractFactory factory1 = new ConcreteFactory1();ProductA productA1 = factory1.createProductA();ProductB productB1 = factory1.createProductB();productA1.showInfo();productB1.showInfo();AbstractFactory factory2 = new ConcreteFactory2();ProductA productA2 = factory2.createProductA();ProductB productB2 = factory2.createProductB();productA2.showInfo();productB2.showInfo();}
}

在这个示例中,AbstractFactory 是抽象工厂接口,ConcreteFactory1ConcreteFactory2 是具体工厂类,分别生产不同系列的产品。每个具体工厂类实现了创建一组相关产品的方法。这就是抽象工厂模式的示例。

区别:

抽象工厂模式(Abstract Factory Pattern)和工厂方法模式(Factory Method Pattern)是两种不同的设计模式,它们都属于创建型模式,用于创建对象。它们之间的区别在于抽象程度和用途。

  1. 抽象工厂模式

    • 抽象工厂模式用于创建一组相关或相互依赖的对象,这些对象通常属于不同的产品族。
    • 它包含一个抽象工厂接口,该接口声明了一组用于创建不同类型产品的抽象方法。每个具体工厂类实现了这些方法以创建特定产品族的对象。
    • 抽象工厂模式强调创建一组对象,通常涉及多个产品接口和多个产品实现类。
  2. 工厂方法模式

    • 工厂方法模式用于创建单一对象,但是通过子类来决定实例化哪个类。
    • 它包含一个抽象工厂基类(接口或抽象类),该基类声明了一个用于创建对象的抽象方法。每个具体工厂子类实现这个方法以返回特定的产品对象。
    • 工厂方法模式强调创建单一对象,每个工厂子类负责创建一种产品。

总结:

       抽象工厂模式关注于一组相互关联的产品,而工厂方法模式关注于单一产品。抽象工厂模式的实现可能比较复杂,涉及多个产品族,而工厂方法模式通常相对简单,每个子类只负责一个产品。选择哪个模式取决于需求的复杂性和结构的设计。

       抽象工厂模式在工厂模式的基础上扩展了一个维度,不仅关注单一产品的创建,还关注一组相关或相互依赖的产品族的创建。这些产品族通常在业务逻辑上有关联,它们可能共同构成一个完整的功能。

缺点总结:

在抽象工厂模式中,如果你想要增加一个新的产品,比如产品C,你需要在抽象工厂接口(或抽象类)中添加一个新的方法来创建该产品。然后,所有的具体工厂类都必须实现这个新方法,为产品C提供实现。这会导致两个问题:

  1. 修改抽象类或接口: 在这个例子中,你需要在AbstractCreator中增加一个createProductC()方法,并且ConcreteFactory1 和ConcreteFactory2都必须实现这个方法。这违反了开闭原则,即系统应该对扩展开放,对修改关闭。

  2. 影响已有代码: 增加新方法会影响到所有已经实现了该抽象工厂的具体工厂类,即ConcreteFactory1 和ConcreteFactory2。这可能会导致许多现有的代码需要修改,因此它们与这个变化产生了依赖关系,即所谓的“有毒代码”。

这种情况下,每次需要增加一个新的产品时,都会引发一系列的修改,从而导致系统的脆弱性和不稳定性。这就是抽象工厂模式的一个局限性,特别是当产品族的变化比较频繁时,扩展性不如其他设计模式。

这也是为什么有时候推荐使用工厂方法模式,因为它对于新增产品更具有弹性,不会对已有的代码造成较大的影响。但抽象工厂模式的优势在于它能够同时创建一组相关的产品,适用于需要创建一组具有特定关联性的对象的情况。

但是也有优点,在添加新的产品族时,只需要新增对应的产品接口和实现,而不需要修改已有的工厂类和产品类。这符合开闭原则,允许易于扩展而不影响现有代码。

相关文章:

工厂模式 与 抽象工厂模式 的区别

工厂模式: // 抽象产品接口 interface Product {void showInfo(); }// 具体产品A class ConcreteProductA implements Product {Overridepublic void showInfo() {System.out.println("This is Product A");} }// 具体产品B class ConcreteProductB impl…...

安装虚拟机+安装/删除镜像

安装虚拟机 注意,官网可能无法登录,导致无法从官网下载,就自己去网上搜靠谱的下载,我用的16.2.3 删除镜像 Vm虚拟机怎么删除已经创建的系统?Vm虚拟机创建好之后iso删除方法 - 系统之家 (xitongzhijia.net) 安装镜像…...

MySQL的内置函数复合查询内外连接

文章目录 内置函数时间函数字符串函数数学函数其他函数 复合查询多表笛卡尔积自连接在where中使用子查询多列子查询在from中使用子查询 内连接外连接左外连接右外连接 内置函数 时间函数 函数描述current_date()当前日期current_time()当前时间current_timestamp()当前时间戳…...

操作系统(OS)与系统进程

操作系统(OS)与系统进程 冯诺依曼体系结构操作系统(Operator System)进程基本概念进程的描述(PCB)查看进程通过系统调用获取进程标示符(PID)通过系统调用创建进程(fork)进程状态&…...

防重复提交:自定义注解 + 拦截器(HandlerInterceptor)

防重复提交:自定义注解 拦截器(HandlerInterceptor) 一、思路: 1、首先自定义注解; 2、创建拦截器实现类(自定义类名称),拦截器(HandlerInterceptor); 3…...

Excel中将文本格式的数值转换为数字

在使用excel时,有时需要对数字列进行各种计算,比如求平均值,我们都知道应该使用AVERAGE()函数,但是很多时候结果却“不尽如人意”。 1 问题: 使用AVERAGE函数: 结果: 可以看到单元格左上角有个…...

uni-app开发小程序中遇到的map地图的点聚合以及polygon划分区域问题

写一篇文章来记录以下我在开发小程序地图过程中遇到的两个小坑吧,一个是点聚合,用的是joinCluster这个指令,另一个是polygon在地图上划分多边形的问题: 1.首先说一下点聚合问题,由于之前没有做过小程序地图问题&#…...

【笔记】软件测试的艺术

软件测试的心理学和经济学 测试是为发现错误而执行程序的过程,所以它是一个破坏性的过程,测试是一个“施虐”的过程。 软件测试的10大原则 1、测试用例需要对预期输出的结果有明确的定义 做这件事的前提是能够提前知晓需求和效果图,如果不…...

配置本地maven

安装maven安装包 修改环境变量 vim ~/.bash_profile export JMETER_HOME/Users/yyyyjinying/apache-jmeter-5.4.1 export GOROOT/usr/local/go export GOPATH/Users/yyyyjinying/demo-file/git/backend/go export GROOVY_HOME/Users/yyyyjinying/sortware/groovy-4.0.14 exp…...

C# 按钮的AcceptButton和CancelButton属性

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System...

SMT贴片制造:专业、现代、智能的未来之选

在现代科技的快速发展下,SMT贴片制造作为电子元器件的核心工艺之一,正以其专业、现代和智能的特点成为未来的首选。 随着电子产品越来越小型化,传统的手工焊接已经无法满足高速、高精度、高稳定性的要求。而SMT贴片制造作为一种先进的表面贴…...

python sqlalchemy db.session 的commit()和colse()对session中的对象的影响

实验一:commit()之后查看stu的属性id,查看db.session是否改变 db_test.route("/db_test",methods["GET"]) def db_test():stuStuTest()stu.stu_age22stu.stu_name"nnannns"stu.stu_class11print("sessio…...

python读取图像小工具

一、和图像交互获得图像的坐标和像素值 import cv2 import numpy as np import signal import threading import timeif __name__ __main__:img cv2.imread(XXX,0)#读取图片font_face,font_scale,thicknesscv2.FONT_HERSHEY_SIMPLEX,0.5,1#鼠标交互def mouseHandler(event,x…...

【ES6】JavaScript中Reflect

Reflect是JavaScript中的一个内建对象,它提供了一组方法,用于对对象和函数进行操作和检查。这些方法与内建对象的方法非常相似,但具有更高的灵活性。 以下是Reflect对象的一些常用方法: 1、Reflect.apply(target, thisArgument,…...

Ajax + Promise复习简单小结simple

axios使用 先看看老朋友 axios axios是基于Ajaxpromise封装的 看一下他的简单使用 安装:npm install axios --save 引入:import axios from axios GitHub地址 基本使用 axios({url: http://hmajax.itheima.net/api/province}).then(function (result…...

WebDAV之π-Disk派盘 + 小书匠

小书匠是一款功能丰富,强大的知识管理工具。全平台覆盖,离线数据存储,自定义数据服务器,所见即所得的 markdown 编辑体验。 小书匠提供了多种实用的编辑模式,例如:栏编辑、双栏编辑、三栏编辑、全屏写作、全屏阅读等。并且该软件还提供了许多有用的扩展语法,比如Latex公…...

LTE ATTACH流程、PDN流程、PGW地址分配介绍

1、S-GW\P-GW选择 MME根据S-GW和P-GW的拓扑信息进行S-GW/P-GW的选择,在S-GW的候选序列和P-GW的候选序列中比较,寻找是否有合一的S-GW/P-GW,并且根据S-GW的优先级和权重信息进行排序,得到S-GW/P-GW的候选组。 2、SGW>PGW连接 PD…...

SQL sever中用户管理

目录 一、用户管理常见方法 二、用户管理方法示例 2.1. 创建登录账户: 2.1.1 检查是否创建账户成功: 2.2. 创建数据库用户: 2.2.1检查用户是否创建成功: 2.3. 授予权限: 2.3.1授予 SELECT、INSERT 和 U…...

linux————pxe网络批量装机

目录 一、概述 什么是pxe pxe组件 二、搭建交互式pxe装机 一、配置基础环境 二、配置vsftpd 三、配置tftp 四、准备pxelinx.0文件、引导文件、内核文件 一、准备pxelinux.0 二、准备引导文件、内核文件 五、配置dhcp 一、安装dhcp 二、配置dhcp 六、创建default文…...

处理时延降低24倍,联通云粒数据引擎优化实践

*作者:郑扬勇,云粒星河数据中台产品负责人 云粒智慧科技有限公司成立于 2018 年 6 月,是中国联通集团混改以来成立的首家合资公司,是中国智慧城市数智化建设者。一直以来,云粒智慧以数字化、智能化、集约化产品为核心&…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

PHP和Node.js哪个更爽?

先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

EtherNet/IP转DeviceNet协议网关详解

一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...

Go语言多线程问题

打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析,分为​​已启动​​和​​未启动​​两种场景: 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​:当其他组件(如Activity、Service)通过ContentR…...

Kafka主题运维全指南:从基础配置到故障处理

#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...