全面升级的对象创建——抽象工厂模式(Python实现和JAVA实现)

1. 引言

大家好!在之前的文章中,我们探讨了简单工厂和工厂方法模式:

轻松创建对象——简单工厂模式(Python实现)
轻松创建对象——简单工厂模式(Java实现)
灵活多变的对象创建——工厂方法模式(Python实现)
灵活多变的对象创建——工厂方法模式(Java实现)

今天,我们要把工厂模式升级到一个新的层次——抽象工厂模式,抽象工厂模式不仅能创建单一对象,还能创建一系列相关的对象;这就像拥有了一个高级的魔法工厂,不仅能生产魔法扫帚,还能生产魔法药水。今天,我们就来揭开抽象工厂模式的神秘面纱,让你的代码更加高效强大。准备好了吗?Let’s go!

2. 什么是抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供一个接口,用于创建相关或依赖对象的家族,而无需明确指定具体类。抽象工厂模式通过组合多个工厂方法,使得我们可以创建一系列相关的对象。

抽象工厂模式的优点包括:

  • 分离接口和实现:通过抽象工厂定义对象的创建接口,具体实现交由子类完成。
  • 提高一致性:确保一系列对象之间的关系和约束。

但也有一些缺点:

  • 复杂性增加:增加了系统的复杂性,理解和实现起来需要更多的时间和精力。
  • 扩展困难:增加新的产品族会涉及到抽象工厂和具体工厂的修改,违反开闭原则。

3. 抽象工厂模式的实现(Python)

示例:形状和颜色工厂

假如你是个魔法师,需要创建各种形状和颜色的魔法物品,你可以用抽象工厂模式来实现这一需求:

代码实现
from abc import ABC, abstractmethod# 定义Shape接口
class Shape(ABC):@abstractmethoddef draw(self):pass# 定义具体的Shape类
class Circle(Shape):def draw(self):print("Drawing a Circle")class Square(Shape):def draw(self):print("Drawing a Square")# 定义Color接口
class Color(ABC):@abstractmethoddef fill(self):pass# 定义具体的Color类
class Red(Color):def fill(self):print("Filling with Red")class Blue(Color):def fill(self):print("Filling with Blue")# 定义AbstractFactory接口
class AbstractFactory(ABC):@abstractmethoddef create_shape(self):pass@abstractmethoddef create_color(self):pass# 定义具体工厂类
class ShapeFactory(AbstractFactory):def create_shape(self):return Circle()def create_color(self):return Noneclass ColorFactory(AbstractFactory):def create_shape(self):return Nonedef create_color(self):return Red()# 使用示例
if __name__ == "__main__":shape_factory = ShapeFactory()shape = shape_factory.create_shape()shape.draw()  # 输出: Drawing a Circlecolor_factory = ColorFactory()color = color_factory.create_color()color.fill()  # 输出: Filling with Red
详细代码解析
  • ShapeColor是抽象基类,定义了各自的抽象方法;
  • CircleSquare类实现了Shape接口,RedBlue类实现了Color接口;
  • AbstractFactory是一个抽象基类,定义了创建ShapeColor对象的抽象方法;
  • ShapeFactoryColorFactory类分别实现了AbstractFactory接口,并返回各自的对象实例;
  • 你可以通过调用具体的工厂类(如ShapeFactoryColorFactory)来创建形状和颜色对象,然后调用相应的方法。

4. 抽象工厂模式的实现(JAVA)

// 定义Shape接口
public interface Shape {void draw();
}// 定义具体的Shape类
public class Circle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a Circle");}
}public class Square implements Shape {@Overridepublic void draw() {System.out.println("Drawing a Square");}
}// 定义Color接口
public interface Color {void fill();
}// 定义具体的Color类
public class Red implements Color {@Overridepublic void fill() {System.out.println("Filling with Red");}
}public class Blue implements Color {@Overridepublic void fill() {System.out.println("Filling with Blue");}
}// 定义AbstractFactory接口
public interface AbstractFactory {Shape createShape();Color createColor();
}// 定义具体工厂类
public class ShapeFactory implements AbstractFactory {@Overridepublic Shape createShape() {return new Circle();}@Overridepublic Color createColor() {return null;}
}public class ColorFactory implements AbstractFactory {@Overridepublic Shape createShape() {return null;}@Overridepublic Color createColor() {return new Red();}
}// 使用示例
public class AbstractFactoryDemo {public static void main(String[] args) {AbstractFactory shapeFactory = new ShapeFactory();Shape shape = shapeFactory.createShape();shape.draw();  // 输出: Drawing a CircleAbstractFactory colorFactory = new ColorFactory();Color color = colorFactory.createColor();color.fill();  // 输出: Filling with Red}
}
详细代码解析
  • ShapeColor是接口,定义了各自的方法;
  • CircleSquare类实现了Shape接口,RedBlue类实现了Color接口;
  • AbstractFactory是一个接口,定义了创建ShapeColor对象的方法;
  • ShapeFactoryColorFactory类分别实现了AbstractFactory接口,并返回各自的对象实例;
  • 你可以通过调用具体的工厂类(如ShapeFactoryColorFactory)来创建形状和颜色对象,然后调用相应的方法。

5. 抽象工厂模式的优缺点

优点
  • 分离接口和实现:通过抽象工厂定义对象的创建接口,具体实现交由子类完成。
  • 提高一致性:确保一系列对象之间的关系和约束。
缺点
  • 复杂性增加:增加了系统的复杂性,理解和实现起来需要更多的时间和精力。
  • 扩展困难:增加新的产品族会涉及到抽象工厂和具体工厂的修改,违反开闭原则。

6. 图示

类图

../_images/AbatractFactory.jpg

示意图

img

7. 总结

抽象工厂模式是一个非常强大的设计模式,通过定义一个接口来创建相关或依赖对象的家族,可以有效地提高代码的一致性和可维护性。虽然它会增加系统的复杂性,但在大型项目中,抽象工厂模式依然是一个非常实用的解决方案。希望今天的分享能让大家对抽象工厂模式有更深入的理解。如果你在项目中也用到了抽象工厂模式,欢迎留言分享你的经验和见解!

附录:工厂模式对比

最后,我们来对比一下三种工厂模式的优缺点,以及它们各自适用的场景:

简单工厂模式
  • 优点

    • 简单易懂,适合小型项目。
    • 客户端只需知道传递的参数,不需要关心具体的创建过程。
  • 缺点

    • 违反开闭原则,每增加一种产品都需要修改工厂类。
    • 工厂类职责过重,增加了系统复杂性。
  • 适用场景

    • 适用于对象种类较少,创建逻辑不复杂的场景。
工厂方法模式
  • 优点

    • 符合开闭原则,增加新产品时无需修改现有代码。
    • 客户端只需使用工厂接口,不需关心具体产品的创建过程。
  • 缺点

    • 增加了代码复杂度,类的数量增加。
  • 适用场景

    • 适用于创建对象的逻辑复杂,产品种类较多且经常变化的场景。
抽象工厂模式
  • 优点

    • 分离接口和实现,提高代码的一致性和可维护性。
    • 适用于创建一系列相关或依赖的对象。
  • 缺点

    • 系统复杂性增加,理解和实现需要更多的时间和精力。
    • 扩展新产品族较困难,需要修改抽象工厂和具体工厂。
  • 适用场景

    • 适用于需要创建一系列相关或依赖对象的复杂系统。
      在这里插入图片描述

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

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

相关文章

12-《向日葵》

向日葵 向日葵(拉丁文:Helianthus annuusL.),为木兰纲、菊目、菊科、向日葵属的一年生草本植物。高1~3.5米。茎直立,圆形多棱角,质硬被白色粗硬毛。广卵形的叶片通常互生,先端锐突或…

PyQt 模拟实现QSignalMapper 实现多个按钮点击监控

QSignalMapper 类用来接受多个信号,将信号汇总后再发射一个新信号。 用处主要是使多个执行类似功能的槽函数化简为一个; QSignalMapper 类在 PyQt 中已经被废弃,并且在较新版本的 PyQt 中已经不存在这个类。 在 PyQt 中,我们可…

传输层协议之UDP

1、端口号 我们在应用层创建的套接字,是需要通过bind()接口绑定我们的IP地址与端口号的,这是因为数据从传输层向上交付到应用层时,需要用端口号来查找特定的服务进程。一般在网络通信时,用IP地址标识一台主机,用端口号…

【linux】【深度学习】fairseq框架安装踩坑

直接pip install fairseq发现跑代码时候老是容易崩,所以选择用源码编译安装。 python环境选择3.8以上都行,我选择3.10 首先安装torch, 我选择安装pip install torch1.13.1 torchaudio0.13.1以及cuda 11.7 (具体cuda根据个人显卡进…

在Linux上导出NFS共享---网络文件系统

目录 一、NFS介绍 二、NFS 所需要的服务 三、搭建NFS服务器共享文件到客户端 在虚拟机129上配置: 在虚拟机135上配置 测试 四、autofs自动挂载 1、安装软件启动 2、编写 /etc/auto.master,在里面添加内容如下 3、编写 /etc/auto.nfs,其内容如下 …

Cisco 命令速查表(非常详细)零基础入门到精通,收藏这一篇就够了

Cisco IOS(Internetwork Operating System)是 Cisco 系统公司开发的专有操作系统,用于其路由器和交换机。它提供了一个稳健的、可扩展的、以命令行接口(CLI)为基础的网络操作环境。通过掌握 Cisco IOS 命令&#xff0c…

Go语言---select

select的作用 Go 里面提供了一个关键字 select,通过 select 可以监听 channel上的数据流动。 select 的用法与switch 语言非常类似,由 select 开始一个新的选择块,每个选择条件由 case语句来描述。 与 switch 语句可以选择任何可使用相等比较…

Spark底层原理:案例解析(第34天)

系列文章目录 一、Spark架构设计概述 二、Spark核心组件 三、Spark架构设计举例分析 四、Job调度流程详解 五、Spark交互流程详解 文章目录 系列文章目录前言一、Spark架构设计概述1. 集群资源管理器(Cluster Manager)2. 工作节点(Worker No…

从汇编层看64位程序运行——栈帧(Stack Frame)边界

大纲 RBP,RSP栈帧边界总结参考资料 在《从汇编层看64位程序运行——栈帧(Stack Frame)入门》中,我们简单介绍了栈帧的概念,以及它和函数调用之间的关系。如文中所述,栈帧是一种虚拟的概念,它表达了一个执行中的函数的栈…

如何找回误删的文件?4个常用文件恢复方法!

对于许多用户来说,误删文件是一种常见而令人懊恼的情况。恢复误删文件的重要性在于,它可以帮助用户找回宝贵的数据,避免因数据丢失带来的各种不便和损失。 如何找回不小心删除的文件? 误删数据不知道怎么恢复,会给我…

kafka部署以及常用命令详细总结

1环境准备 1.1ip规划 ip: 192.168.1.200 1.2配置主机名 #设置主机名 hostnamectl set-hostname node11.3配置hosts [rootnode1 ~]# cat >> /etc/hosts << EOF192.168.1.200 node1 EOF2部署 2.1安装包准备 将以下安装包从官网下载到本地 jdk-8u371-linux-x6…

如何使用键盘优雅地使用浏览器

来自&#x1f96c;&#x1f436;程序员 Truraly | 田园 的博客&#xff0c;最新文章首发于&#xff1a;田园幻想乡 | 原文链接 | github &#xff08;欢迎关注&#xff09; 目录 浏览器快捷键 参考资料&#xff1a; 教你如何用键盘轻松浏览网页 这两天出门旅游&#xff0c;高铁…

Vue单路由的独享守卫怎么设置

在Vue.js中&#xff0c;特别是在使用Vue Router时&#xff0c;路由守卫&#xff08;Route Guards&#xff09;是一种强大的机制&#xff0c;允许我们在路由发生变化时执行一些逻辑&#xff0c;比如检查用户是否登录、加载数据等。Vue Router提供了全局守卫、路由独享守卫和组件…

美团一面,你碰到过CPU 100%的情况吗?你是怎么处理的?

本文主要分为三部分 分析一下CPU 100%的常见原因 CPU 100%如何排查 回答这个问题的一个参考答案 CPU被打满的常见原因 1. 死循环 在实际工作中&#xff0c;可能每个开发都写过死循环的代码。 死循环有两种&#xff1a; 在 while、for、forEach 循环中的死循环。 无限递…

centos安装minio文件系统服务器(踩坑版)

centos安装minio文件系统服务器&#xff08;踩坑版&#xff09; 引安装1. 下载2. 启动3. 创建access keys4. 创建buckets 坑 引 本来安装挺简单的&#xff0c;网上的教程一大堆&#xff0c;有些写的也挺详细的。不过自己还是踩到坑了&#xff0c;耽误了个把小时&#xff0c;特…

【分库】分库的核心原则

目录 分库的核心原则 前言 分区透明性与一致性保证 弹性伸缩性与容错性设计 数据安全与访问控制机制 分库的核心原则 前言 在设计和实施分库策略时&#xff0c;遵循一系列核心原则是至关重要的&#xff0c;以确保系统不仅能够在当前规模下高效运行&#xff0c;还能够随着…

Vue的生命周期函数有哪些?

Vue的生命周期函数是指Vue实例从创建到销毁的过程中&#xff0c;会调用的一系列特殊函数&#xff0c;这些函数允许开发者在Vue的不同阶段执行特定的代码。Vue 2.x和Vue 3.x的生命周期函数有所差异&#xff0c;但总体思路是一致的。以下是Vue生命周期函数的主要分类和具体函数&a…

单目测距 单目相机测距 图片像素坐标转实际坐标的一种转换方案

需要相机位置固定 原图 红色的点是我们标注的像素点&#xff0c;这些红色的点我们知道它的像素坐标&#xff0c;以及以右下角相机位置为原点的x y 实际坐标数值 通过转换&#xff0c;可以得到整个图片内部其余像素点的实际坐标&#xff0c; 这些红色的点是通过转换关系生成的&…

Python | Leetcode Python题解之第231题2的幂

题目&#xff1a; 题解&#xff1a; class Solution:BIG 2**30def isPowerOfTwo(self, n: int) -> bool:return n > 0 and Solution.BIG % n 0

el-table 动态添加删除 -- 鼠标移入移出显隐删除图标

<el-table class"list-box" :data"replaceDataList" border><el-table-column label"原始值" prop"original" align"center" ><template slot-scope"scope"><div mouseenter"showClick…