工厂模式:没你想像的那么难

工厂模式

工厂模式是一种创建型设计模式,它允许创建对象而无需指定将要创建的对象的具体类。它通过将对象的创建委托给一个单独的方法或类来完成,从而隐藏了对象的实例化逻辑。这样可以提高代码的灵活性,减少了代码中的重复和耦合。

在工厂模式中通常会包含以下几个要素:

  • 产品接口(Product Interface):定义了要创建的对象的通用接口。
  • 具体产品(Concrete Product):实现了产品接口的具体对象。
  • 工厂接口(Factory Interface):定义了一个创建对象的方法,通常是一个接口或者抽象类。
  • 具体工厂(Concrete Factory):实现了工厂接口,负责创建具体产品的对象。

现在,让我们通过一个 Python 示例来说明工厂模式的用法。假设我们有一个简单的图形绘制应用,它可以绘制圆形和矩形。我们将使用工厂模式来创建这些形状对象。

# 产品接口:形状
class Shape:
    def draw(self):
        pass

# 具体产品:圆形
class Circle(Shape):
    def draw(self):
        print("Inside Circle::draw() method.")

# 具体产品:矩形
class Rectangle(Shape):
    def draw(self):
        print("Inside Rectangle::draw() method.")

# 工厂接口
class ShapeFactory:
    def create_shape(self, shape_type):
        pass

# 具体工厂:形状工厂
class SimpleShapeFactory(ShapeFactory):
    def create_shape(self, shape_type):
        if shape_type.lower() == "circle":
            return Circle()
        elif shape_type.lower() == "rectangle":
            return Rectangle()
        else:
            raise ValueError("Unsupported shape type: " + shape_type)

# 客户端代码
if __name__ == "__main__":
    # 创建形状工厂对象
    shape_factory = SimpleShapeFactory()

    # 根据工厂创建形状对象
    circle = shape_factory.create_shape("circle")
    circle.draw()

    rectangle = shape_factory.create_shape("rectangle")
    rectangle.draw()

在这个示例中,我们定义了 Shape 接口作为产品接口,然后实现了具体的产品类 Circle 和 Rectangle。接着,我们定义了一个工厂接口 ShapeFactory 和一个具体工厂类 SimpleShapeFactory,后者实现了创建形状对象的方法 create_shape。最后,在客户端代码中,我们使用工厂对象来创建具体的形状对象,而无需直接实例化具体的产品类。

这种设计使得客户端代码与具体的产品类解耦,使得在需要添加新的产品类型时,只需要修改工厂类而无需修改客户端代码,从而提高了代码的可维护性和可扩展性。

抽象工厂模式

抽象工厂模式是一种创建型设计模式,它提供了一种创建一系列相关或依赖对象的方法,而无需指定其具体类。该模式通过引入抽象工厂和具体工厂来实现,从而使得客户端代码与具体产品类的实现相互独立。

抽象工厂模式通常涉及以下几个关键组件:

  • 抽象工厂(Abstract Factory):定义了一组方法,用于创建一系列相关或依赖对象的抽象接口。
  • 具体工厂(Concrete Factory):实现了抽象工厂接口,并负责创建具体产品族的对象。
  • 抽象产品(Abstract Product):定义了一组相关或依赖对象的抽象接口。
  • 具体产品(Concrete Product):实现了抽象产品接口的具体对象。

抽象工厂模式与工厂模式相比,其可以创建一组相关的对象,而不仅仅是单个对象。

下面是一个简单的 Python 示例,演示了抽象工厂模式的应用。假设我们有一个图形界面库,它包含按钮和文本框两种组件,我们可以根据不同的操作系统(例如 Windows 和 macOS)创建对应的按钮和文本框。

# 抽象产品:按钮接口
class Button:
    def paint(self):
        pass

# 具体产品:Windows 按钮
class WindowsButton(Button):
    def paint(self):
        print("Rendering a Windows style button.")

# 具体产品:macOS 按钮
class MacOSButton(Button):
    def paint(self):
        print("Rendering a macOS style button.")

# 抽象产品:文本框接口
class TextBox:
    def paint(self):
        pass

# 具体产品:Windows 文本框
class WindowsTextBox(TextBox):
    def paint(self):
        print("Rendering a Windows style text box.")

# 具体产品:macOS 文本框
class MacOSTextBox(TextBox):
    def paint(self):
        print("Rendering a macOS style text box.")

# 抽象工厂:UI 工厂接口
class UIFactory:
    def create_button(self):
        pass

    def create_text_box(self):
        pass

# 具体工厂:Windows UI 工厂
class WindowsUIFactory(UIFactory):
    def create_button(self):
        return WindowsButton()

    def create_text_box(self):
        return WindowsTextBox()

# 具体工厂:macOS UI 工厂
class MacOSUIFactory(UIFactory):
    def create_button(self):
        return MacOSButton()

    def create_text_box(self):
        return MacOSTextBox()

# 客户端代码
if __name__ == "__main__":
    # 根据当前操作系统选择对应的 UI 工厂
    os = "windows"  # 可以根据实际情况修改
    if os.lower() == "windows":
        ui_factory = WindowsUIFactory()
    elif os.lower() == "macos":
        ui_factory = MacOSUIFactory()
    else:
        raise ValueError("Unsupported operating system: " + os)

    # 使用 UI 工厂创建按钮和文本框
    button = ui_factory.create_button()
    text_box = ui_factory.create_text_box()

    # 渲染按钮和文本框
    button.paint()
    text_box.paint()

在这个示例中,我们定义了抽象产品接口 Button 和 TextBox,以及两种具体产品类(Windows 和 macOS 版本)。然后,我们定义了抽象工厂接口 UIFactory 和两个具体工厂类(WindowsUIFactory 和 MacOSUIFactory),分别用于创建 Windows 和 macOS 版本的按钮和文本框。最后,在客户端代码中,我们根据当前操作系统选择对应的工厂,并使用工厂创建按钮和文本框,然后调用它们的渲染方法。

 查看原文:工厂模式:没你想像的那么难

关注公众号 "字节航海家" 及时获取最新内容

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

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

相关文章

css【详解】—— 圣杯布局 vs 双飞翼布局 (含手写清除浮动 clearfix)

两者功能效果相同&#xff0c;实现方式不同 效果预览 两侧宽度固定&#xff0c;中间宽度自适应&#xff08;三栏布局&#xff09;中间部分优先渲染允许三列中的任意一列成为最高列 圣杯布局 通过左右栏填充容器的左右 padding 实现&#xff0c;更多细节详见注释。 <!DOCTYP…

MySQL:数据库中有哪些锁

1、全局锁 加上全局锁后整个数据库就处于只读状态了&#xff0c;这时其他线程执行以下操作&#xff0c;都会被阻塞&#xff1a; 对数据的增删改操作&#xff0c;比如 insert、delete、update等语句&#xff1b;对表结构的更改操作&#xff0c;比如 alter table、drop table 等…

【AI+应用】怎么快速制作一个类chatGPT套壳网站

最近有人问我&#xff0c; 看了我之前写的一篇文章 [人工智能] AI浪潮下Sora对于普通人的机会 &#xff0c; 怎么做一个类chatGPT的套壳网站&#xff0c;是从0开始做么。 对于普通人来说&#xff0c;万事不懂先AI&#xff0c; AI找不到答案搜索google或百度。对于程序员来说…

电梯物联网之梯控相机方案-防止电瓶车进电梯

梯控现状 随着电梯产品在智能化建筑的日益普及,对于电梯的智能化管理 安全性需求 的要求越来越迫切。尤其今年来随着电瓶车的大量普及&#xff0c;发起多起楼道、轿厢电瓶车着火恶性事件&#xff0c; 造成了极大的社会 负面影响。控制电瓶车进入单元门&#xff0c;楼道以及电梯…

设计师面试作品集注意!避免以下6个陷阱!

作品集是设计师提交简历和面试的关键。因此&#xff0c;与其担心自己学历低&#xff0c;不懂谈判技巧&#xff0c;不如多关注作品集。看了很多设计师的简历和作品集&#xff0c;发现下面的坑经常被踩。为了避免这些坑&#xff0c;建议您选择即时设计来制作作品集&#xff0c; …

如何压缩pdf文件?几种高效压缩方法收好

如何压缩pdf文件&#xff1f;在日常工作和生活中&#xff0c;我们经常会在工作中使用pdf文件。然而&#xff0c;有时候过大的PDF文件会给我们的传输和存储带来不便。那么&#xff0c;如何有效地压缩PDF文件呢&#xff1f;本文将为你详细介绍几种简单实用的方法&#xff0c;让你…

MySQL 用了哪种默认隔离级别,实现原理是什么?

MySQL 的默认隔离级别是 RR - 可重复读&#xff0c;可以通过命令来查看 MySQL 中的默认隔离级别。 RR - 可重复读是基于多版本并发控制&#xff08;Multi-Version Concurrency Control&#xff0c;MVCC &#xff09;实现的。MVCC&#xff0c;在读取数据时通过一种类似快照的方…

优思学院|3步骤计算出Cpk|学习Minitab

在生产和质量管理中&#xff0c;准确了解和控制产品特性至关重要。一个关键的工具是Cpk值&#xff0c;它是衡量生产过程能力的重要指标。假设我们有一个产品特性的规格是5.080.02&#xff0c;通过收集和分析过程数据&#xff0c;我们可以计算出Cpk值&#xff0c;进而了解生产过…

AI 越来越强大,创造性工作会被取代吗?

AI发展迅猛&#xff0c;据不完全数据统计2023年AI大模型就有200之多&#xff0c;文心一言、通义千问、讯飞星火以及一下不知名的聚合平台 雨后春笋般的出现&#xff0c;那么AI是否可以直接去掉现在的部分工作呢&#xff1f; 针对以上咱们针对AI技术对工作影响做一下分析&#x…

SpringBoot【问题 05】PostgreSQL数据库启用SSL后使用默认配置进行数据库连接(Navicat工具与Java程序)

官网SSL说明&#xff1a;https://www.postgresql.org/docs/9.1/libpq-ssl.html 1.配置 1.1 文件 使用SSL需要的4个文件&#xff0c;名称要一致&#xff1a; 客户端密钥&#xff1a;postgresql.keyJava客户端密钥&#xff1a;postgresql.pk8客户端证书&#xff1a;postgresq…

vue中element-ui中的el-button自定义icon图标

实现&#xff1a; button的icon属性自定义一个图标名称&#xff0c;这个自定义的图标名称会默认添加到button下i标签的class上&#xff0c;我们只需要设置i标签的样式就可以了。 1. 控制台显示的代码 2 .图片展示 3. 按钮上使用自定义的icon 完整代码&#xff1a; <el-but…

初学者如何使用QT新建一个包含UI界面的C++项目

文章目录 一、下载并安装QT51、下载安装包2、注册/登录账号3、安装qt6 二、新建QT Widget项目1、新建项目并且运行2、易错点&#xff1a;可能运行成功得到UI界面但是会报错&#xff08;原因是使用了中文路径&#xff09; 一、下载并安装QT5 1、下载安装包 进入下载网址 Windo…

钉钉机器人发送折线图卡片 工具类代码

钉钉机器人 “创建并投放卡片 接口 ” 可以 发送折线图、柱状图 官方文档&#xff1a;创建并投放卡片 - 钉钉开放平台 0依赖、1模板、2机器人放到内部应用、3放开这个权限 、4工具类、5调用工具类 拼接入参 卡片模板 自己看文档创建&#xff0c;卡片模板的id 有用 0、依赖…

c语言经典测试题8

在c语言经典测试题6的第一题&#xff0c;大家是否想过可不可以将递归参数改为s呢&#xff1f;或许有的人已经试过了&#xff0c;但是发现好像不会有结果&#xff0c;其实是因为s为后置&#xff0c;先试用后加1&#xff0c;然而我们这个是在s出了函数之后才会运行加1操作&#x…

响应式编程

编程范式 编程范式是一种编程风格或方法论&#xff0c;它规定了解决问题和实现计算机程序的基本方法。不同的编程范式强调不同的编程思想和原则。 面向对象编程 函数式编程 lambda是重要特征&#xff0c;以函数为基本单位。 响应式编程 异步数据流交互性强&#xff0c;实时…

《HelloGitHub》第 95 期

兴趣是最好的老师&#xff0c;HelloGitHub 让你对编程感兴趣&#xff01; 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 Python、Java、Go、C/C、Swift...让你在短时间内…

FRM模型十二:极值理论

目录 极值理论介绍GEVPOT 代码实现 极值理论介绍 在风险管理中&#xff0c;将事件分为高频高损、高频低损、低频高损、低频低损。其中低频高损是一种非常棘手的损失事件&#xff0c;常出现在市场大跌、金融体系崩溃、金融危机以及自然灾害等事件中。 由于很难给极端事件一个准…

案例研究|DataEase助力众陶联应对产业链数据可视化挑战

佛山众陶联供应链服务有限公司&#xff08;以下简称为“众陶联”&#xff09;成立于2016年&#xff0c;是由34家陶瓷企业共同创办的建陶行业工业互联网平台&#xff0c;股东产值占整个行业的22.5%。众陶联以数据赋能为核心&#xff0c;积极探索新的交易和服务模式&#xff0c;构…

智能高侧开关PC8818单通道 40V 80mΩ提供保护和诊断功能高边开关芯片

概述 PC8818是一个80mΩRDS&#xff08;ON&#xff09;高侧开关&#xff0c;提供充分的保护和诊断功能。此设备有两个版本。对于版本A&#xff0c;设备报告FLTn引脚开路排水结构的故障情况。对于版本B&#xff0c;其ISNS引脚输出小电流与流经内部的电流成比例功率FET。用户可以…

Lumerical ------ 文件清理与系统存储空间释放

Lumerical ------ 文件清理与系统存储空间释放 推荐阅读引言正文推荐阅读 Lumerical—文件名后缀的含义 引言 在使用 Lumerical 的过程中,有很多小伙伴们会在运行完成后选择保存工程文件并退出,这样下次进入 .fsp 文件的时候之前的仿真结构和仿真结果都能够得到很好地保存…