深入理解抽象工厂模式:原理、应用与优缺点分析

文章目录

  • **一、模式原理**
  • **二、使用场景**
  • **三、为何使用抽象工厂模式**
  • 四、代码示例
  • **五、优点与缺点**
  • **总结**

一、模式原理

​ 抽象工厂模式是一种创建型设计模式,其核心思想在于通过抽象工厂接口提供一个创建一系列相关或相互依赖对象的接口,而不必指定具体的类。该模式适用于在多种不同条件下,需要创建一组具有共同接口但实现不同的对象的情况。

在抽象工厂模式中,主要包括以下角色:

在这里插入图片描述

  • 抽象工厂:定义创建一系列相关或相互依赖对象的接口。
  • 抽象产品:定义了一组相关或相互依赖的产品接口或抽象类。
  • 具体工厂:实现了抽象工厂接口,用于创建具体的产品对象。
  • 具体产品:实现了抽象产品接口,是工厂方法创建的实际对象。

举例说明,抽象工厂可以是家具工厂,抽象产品是一系列家具(椅子、桌子、沙发),具体工厂则代表不同风格或产地的家具工厂,如中国工厂或美国工厂,它们产出的具体产品分别是中国风格或美国风格的椅子、桌子和沙发。

二、使用场景

抽象工厂模式常见于以下场景:

  1. 跨平台兼容性问题:如在应用程序中根据不同操作系统选择合适的驱动程序集合。
  2. 组件复用性需求:如在不同数据库产品间利用JDBC实现数据库操作的统一接口。
  3. 提升代码扩展性和降低维护成本:如日志监控系统的实现,允许通过抽象日志工厂创建不同日志收集代理。

三、为何使用抽象工厂模式

使用抽象工厂模式的原因主要包括:

  1. 提高组件复用性:对于具有相似特征的不同产品系列,通过抽象工厂模式可以提高组件的互换性和重用性。
  2. 提升代码扩展性和维护性:将对象创建和使用过程解耦,使得增加新工厂或新产品的系列变得相对容易,且不影响已有功能。
  3. 解决跨平台兼容问题:通过提供高层级的抽象功能接口,确保不同平台或环境下的客户端都能获得一致的服务。

四、代码示例

以上述家具工厂为例:

首先,定义抽象产品接口和具体产品类:

// 抽象产品接口
public interface Furniture {
    void produce();
}

// 具体产品类 - 中国风格椅子
public class ChineseChair implements Furniture {
    @Override
    public void produce() {
        System.out.println("生产中国风格椅子");
    }
}

// 具体产品类 - 中国风格沙发
public class ChineseSofa implements Furniture {
    @Override
    public void produce() {
        System.out.println("生产中国风格沙发");
    }
}

// 具体产品类 - 美国风格椅子
public class AmericanChair implements Furniture {
    @Override
    public void produce() {
        System.out.println("生产美国风格椅子");
    }
}

// 具体产品类 - 美国风格沙发
public class AmericanSofa implements Furniture {
    @Override
    public void produce() {
        System.out.println("生产美国风格沙发");
    }
}

接着,定义抽象工厂接口以及具体工厂类:

// 抽象工厂接口
public interface FurnitureFactory {
    Furniture createChair();
    Furniture createSofa();
}

// 具体工厂类 - 中国家具工厂
public class ChineseFurnitureFactory implements FurnitureFactory {
    @Override
    public Furniture createChair() {
        return new ChineseChair();
    }

    @Override
    public Furniture createSofa() {
        return new ChineseSofa();
    }
}

// 具体工厂类 - 美国家具工厂
public class AmericanFurnitureFactory implements FurnitureFactory {
    @Override
    public Furniture createChair() {
        return new AmericanChair();
    }

    @Override
    public Furniture createSofa() {
        return new AmericanSofa();
    }
}

然后,客户端代码使用抽象工厂创建家具:

public class Client {
    public static void main(String[] args) {
        // 使用中国家具工厂创建家具
        FurnitureFactory chineseFactory = new ChineseFurnitureFactory();
        Furniture chineseChair = chineseFactory.createChair();
        Furniture chineseSofa = chineseFactory.createSofa();
        chineseChair.produce();
        chineseSofa.produce();

        System.out.println("\n------------------------\n");

        // 使用美国家具工厂创建家具
        FurnitureFactory americanFactory = new AmericanFurnitureFactory();
        Furniture americanChair = americanFactory.createChair();
        Furniture americanSofa = americanFactory.createSofa();
        americanChair.produce();
        americanSofa.produce();
    }
}

运行 Client 类的 main 方法,可以看到输出:

在这里插入图片描述

​ 通过这段代码,我们清晰地展示了抽象工厂模式的运作流程:客户端通过抽象工厂接口创建所需的产品,无需关心具体产品是由哪个具体工厂实现的,从而实现了对象的创建和使用相分离,提高了系统的灵活性和扩展性。

五、优点与缺点

优点:

  1. 符合开闭原则,易于添加新工厂类。
  2. 确保同一家工厂生产的系列产品一致性。
  3. 降低耦合度,实现使用和创建的解耦。
  4. 遵循单一职责原则,增强代码的可维护性。
  5. 新增产品系列便捷,只需基于已有抽象工厂扩展。

缺点:

  1. 增加代码量,可能导致开发时间和维护成本上升。
  2. 学习成本较高,寻找正确的抽象设计具有一定挑战性。
  3. 修改产品结构较难,牵一发动全身,变更可能影响所有具体工厂和抽象工厂。

总结

​ 抽象工厂模式的成功运用关键在于能否找到正确的抽象层次。在实践中,开发者应首先识别出具有高度可复用性的抽象产品,然后再构建相应的具体工厂和产品。尽管在日常业务代码开发中较少直接应用抽象工厂模式,但它在许多优秀的开源框架中扮演了重要角色,体现了设计模式在软件架构层面的重要性。在选择设计模式时,应充分考虑项目需求和长期维护性,合理权衡是否采用抽象工厂模式。若仅需封装单个对象的创建过程,工厂方法模式可能更为合适。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Rust结构体讲解学习,以及impl结构体方法和结构体关联函数

Rust 中的结构体(Struct)与元组(Tuple)都可以将若干个类型不一定相同的数据捆绑在一起形成整体,但结构体的每个成员和其本身都有一个名字,这样访问它成员的时候就不用记住下标了。元组常用于非定义的多值传…

十六、异常和File

异常和File 一、异常1.1异常的分类1.2 异常的作用1.3 异常的处理方式1.3.1 JVM默认的处理方式1.3.2 自己处理(捕获异常)1.3.3 自己处理(灵魂四问) 1.4 异常中的常见方法1.5 抛出异常综合练习(键盘录入数据)…

nginx-图片模块

./configure --with-http_image_filter_module location / {root html;index index.html index.htm;if ($arg_w "") {set $arg_w -;}if ($arg_h "") {set $arg_h -;}image_filter resize $arg_w $arg_h;image_filter_jpeg_quality 95; } 访问: 1234…

xxl-job--02--可视化界面各功能详细介绍

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 可视化界面1 新增执行器2.新增任务**执行器**:**任务描述**:**路由策略**:**Cron**:cron表达式**运行模式**JobHandl…

Python把excel内容保存为图片(非统计图而是纯原表格数据)

一、引入 excel2img 库,没有的话使用 pip install excel2img进行安装 二、采用如下方法进行图片生成 excel文件名为:111.xlsx excel表格里面的sheet名称列表为 [Sheet1, Sheet2] 最终保存为以sheet名称.png的图片 支持跨表格合并项 import excel2i…

一文扫盲:室内导航系统的应用场景和技术实现(入门级)

hello,我是贝格前端工场,之间搞过一些室内导航项目,有2D也有3D的,算是有些经验,这里给大家分享一下室内导航的基本尝试,欢迎老铁们点赞、关注,如有需求可以私信我们。 一、室内导航是什么 室内…

理解这几个安全漏洞,你也能做安全测试

01 短信炸弹 1、漏洞描述 短信轰炸攻击是常见的一种攻击,攻击者通过网站页面中所提供的发送短信验证码的功能处,通过对其发送数据包的获取后,进行重放,如果服务器短信平台未做校验的情况时,系统会一直去发送短信&…

高斯消元法的应用

如果有这么一个线性规划系统的例子: 添加图片注释,不超过 140 字(可选) 将如上的线性规划系统转换为: 添加图片注释,不超过 140 字(可选) 这里要注意的是转换后的约束条件全部都变…

模版进阶C++

非类型模版 之前我们写的模版都是在不知道模版(类)中有的变量的类型是什么的时候,我们先用模版参数定义,当类实例化的时候在传参确认 非类型模版:模版参数定义的时候也可以定义整型类型(c20之后才支持其…

【剑指offer--C/C++】JZ3 数组中重复的数字

一、题目 二、本人思路及代码 这道题目它要求的时间空间利用率都是n,那么可以考虑创建一个长度为n的数组repeat初始化为0,下标代码出现的数字,下标对应的数组内容代表该下标数字出现的次数。然后遍历提供的数组,每出现一个数字&a…

java011 - Java字符串

1、API 1.1 概念 API(application programming interface)应用编程接口。 1.2 API帮助文档 1.3 API练习 注意:使用快捷键 ctrlalt v 可以直接生存左边的 数据类型 变量 。 完整代码: 2、String 2.1 概述 String类在 java.long 包下,所以使用的时…

LeetCode 刷题 [C++] 第347题.前 K 个高频元素

题目描述 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 题目分析 据题意可知,我们需要先遍历整个数组,并统计每个数字出现的次数,保存在哈希表中;对元素…

C++基于多设计模式下的同步异步日志系统day4

📟作者主页:慢热的陕西人 🌴专栏链接:C基于多设计模式下的同步&异步日志系统 📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言 只要内容主要实现了同步日志消息…

2024年【安全员-C证】及安全员-C证模拟考试题

题库来源:安全生产模拟考试一点通公众号小程序 安全员-C证考前必练!安全生产模拟考试一点通每个月更新安全员-C证模拟考试题题目及答案!多做几遍,其实通过安全员-C证作业模拟考试很简单。 1、【多选题】《劳动法》规定&#xff0…

w30使用python调用shell脚本

使用python脚本去实现永恒之蓝漏洞攻击 实验环境 攻击工具:pythonmsfconsole 靶场:win7 和 kali实验目的 演示python脚本调用过程 实验步骤 1.写一个永恒之蓝的攻击脚本,定义为blue.rc use exploit/windows/smb/ms17_010_eternalblue …

从第一原理看大语言模型

大模型基础框架 大模型幻觉问题 大模型能力 思维链模式 思维链模式激发的是大模型的推理能力 LLM知识能力RAG

深度学习-Softmax 回归 + 损失函数 + 图片分类数据集

Softmax 回归 损失函数 图片分类数据集 1 softmax2 损失函数1均方L1LossHuber Loss 3 图像分类数据集4 softmax回归的从零开始实现 1 softmax Softmax是一个常用于机器学习和深度学习中的激活函数。它通常用于多分类问题,将一个实数向量转换为概率分布。Softmax函…

【黑马程序员】5、TypeScript类型声明文件_黑马程序员前端TypeScript教程,TypeScript零基础入门到实战全套教程

课程地址:【黑马程序员前端TypeScript教程,TypeScript零基础入门到实战全套教程】 https://www.bilibili.com/video/BV14Z4y1u7pi/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 目录 5、TypeScript类型声明文件 5.1 TS中的…

布隆过滤器实战

一、背景 本篇文章以解决实际需求的问题的角度进行切入,探讨了如果使用布隆过滤器快速丢弃无效请求,降低了系统的负载以及不必要的流量。 我们都知道布隆过滤器是以占用内存小,同时也能够实现快速的过滤从而满足我们的需求,本篇…

2.模拟问题——4.日期问题

日期问题难度并不大,但是代码量非常大,需要较高的熟练度,因此需要着重练习,主要涉及数组和循环两个方面的知识点,需要熟练的测试代码。 两个经典题型 闰年 闰年满足以下两个条件的任意一个 能够被400整除不能够被1…