【创建型设计模式】工厂模式

【创建型设计模式】工厂模式

创建型设计模式第二期!本期介绍简单工厂模式和工厂方法模式。

简单工厂模式

简单工厂模式(又叫作静态工厂方法模式),其属于创建型设计模式,简单工厂模式不属于设计模式中的 23 种经典模式。提到它是为了让大家能够更好地理解后面讲到的工厂方法模式。

定义:简单工厂模式属于创建型设计模式,其又被称为静态工厂方法模式,这是由一个工厂对象决定创建出哪一种产品类的实例。

简单工厂模式通过工厂类的静态方法,根据传入的参数创建并返回不同的产品对象。

在简单工厂模式中有如下角色:

  • Factory: 工厂类,这是简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
  • Product: 抽象产品类,这是简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
  • Product: 具体产品类,这是简单工厂模式的创建目标。

省流:

工厂类(Factory):负责创建具体产品实例的类。

抽象产品(Product):所有具体产品的父类或接口。

具体产品(Concrete Product):工厂类所创建的具体对象。

1. 简单工厂模式的简单实现

这里我们用生产计算机来举例,假设有一个计算机的代工生产商,它目前已经可以代工生产联想计算机了。随着业务的拓展,这个代工生产商还要生产惠普和华硕的计算机。这样我们就需用一个单独的类来专门生产计算机,这就用到了简单工厂模式,下面我们来实现简单工厂模式。

(1)抽象产品类 (Shape 接口)
// 抽象产品
public interface Shape {
    void draw();
}

目的

定义统一的产品接口,所有具体产品都必须实现该接口。

面向接口编程:客户端只需要知道 Shape 的接口,而不需要关心具体实现。

优点

增强了代码的灵活性,客户端可以通过 Shape 类型调用 draw 方法,减少对具体类的依赖。

(2)具体产品类(Circle, Rectangle, Triangle 类)
// 圆形
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a Circle");
    }
}

// 矩形
public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a Rectangle");
    }
}

// 三角形
public class Triangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a Triangle");
    }
}
目的

这些类是具体实现,负责实现抽象产品 (Shape) 中的接口方法。

每个具体产品有其独特的行为逻辑。例如,Circle.draw 可能涉及圆的特定绘制逻辑。

优点

将每个形状的行为封装在独立的类中,满足单一职责原则。

(3)工厂类(ShapeFactory)
// 工厂类
public class ShapeFactory {
    public static Shape createShape(String shapeType) {
        if ("circle".equalsIgnoreCase(shapeType)) {
            return new Circle();
        } else if ("rectangle".equalsIgnoreCase(shapeType)) {
            return new Rectangle();
        } else if ("triangle".equalsIgnoreCase(shapeType)) {
            return new Triangle();
        } else {
            throw new IllegalArgumentException("Unknown shape type: " + shapeType);
        }
    }
}

目的

封装对象创建逻辑:工厂类中定义了如何根据传入参数决定返回哪种 Shape 对象。

隐藏具体实现:客户端无需知道具体类名,只需通过简单的字符串参数即可获得对象实例。

实现细节

静态方法 createShape:接收一个字符串 shapeType,通过条件判断实例化对应的 Shape 对象。

错误处理:如果传入的 shapeType 无法匹配现有的类型,则抛出 IllegalArgumentException,确保程序不会意外运行。

优点

客户端与具体实现解耦,符合 依赖倒置原则

通过集中管理对象创建逻辑,可以减少冗余代码。

缺点

每增加一种产品,都需要修改 ShapeFactory 的代码,违反了 开闭原则

(4)客户端调用工厂类
public class Main {
    public static void main(String[] args) {
        // 使用工厂创建对象
        Shape circle = ShapeFactory.createShape("circle");
        circle.draw();

        Shape rectangle = ShapeFactory.createShape("rectangle");
        rectangle.draw();

        Shape triangle = ShapeFactory.createShape("triangle");
        triangle.draw();
    }
}
功能

客户端通过 ShapeFactory 的静态方法获取具体的 Shape 对象。

无需直接调用 new Circle()new Rectangle(),只需提供字符串参数即可完成对象的创建。

优点

客户端的代码更简洁,只需与 ShapeFactoryShape 接口交互。

隐藏了对象的具体实现,降低了耦合性。

2. 使用简单工厂模式的场景和优缺点

1. 客户端不需要关心对象创建的复杂过程

如果对象的创建涉及复杂的逻辑或依赖大量配置参数,而客户端只关心最终的产品实例,则可以使用简单工厂模式。

示例:日志记录系统根据参数返回文件日志、数据库日志、或控制台日志实例。

2. 产品种类有限且变化不频繁

当需要创建的产品种类数量较少,且不需要频繁扩展或修改时,简单工厂是一个快速实现的选择。

示例:为小型电商系统创建不同类型的支付方式(如支付宝、微信支付、信用卡支付)。

3. 需要在运行时动态决定使用哪个产品

当具体产品的选择需要根据运行时的条件决定,而这些条件可以通过参数来表示时,简单工厂模式非常适用。

示例:根据文件类型(如 .txt, .pdf)返回相应的文件解析器对象。

工厂方法模式

工厂方法模式(Factory Method Pattern)是一种 创建型设计模式,它通过定义一个抽象的工厂接口,由子类决定具体实例化的产品对象,从而让对象的创建延迟到子类中进行。

在工厂方法模式中有如下角色:

抽象工厂(Factory Interface/Abstract Factory)

  • 定义工厂的通用接口,提供一个用于创建产品的方法。

具体工厂(Concrete Factory)

  • 实现抽象工厂接口,负责具体产品的实例化。

抽象产品(Product Interface/Abstract Product)

  • 定义产品的公共接口,确保不同的产品有相同的行为。

具体产品(Concrete Product)

  • 实现抽象产品接口,提供具体的产品功能。
image-20241124003745585

工厂方法模式的优缺点

优点

符合开闭原则

  • 增加新产品时,只需添加对应的具体工厂类,而无需修改已有代码。

高内聚低耦合

  • 客户端依赖于抽象工厂和抽象产品,减少了对具体实现的耦合。

代码更灵活

  • 客户端可以通过切换具体工厂来获得不同的产品实例,而无需更改业务代码。
缺点

增加了系统复杂度

  • 每增加一种产品,就需要增加一个具体工厂类,类的数量会随着产品类型的增加而增加。

不适合产品种类较少的场景

  • 如果产品种类较少,使用工厂方法模式可能会导致代码结构过于冗长。

工厂方法模式的简单实现

工厂方法模式的抽象产品类与具体产品类的创建和简单工厂模式是一样的。

(1)创建抽象工厂
// 抽象工厂接口
public interface ParserFactory {
    DocumentParser createParser();
}
(2)创建具体工厂
// Word 文档解析器工厂
public class WordParserFactory implements ParserFactory {
    @Override
    public DocumentParser createParser() {
        return new WordParser();
    }
}

// PDF 文档解析器工厂
public class PdfParserFactory implements ParserFactory {
    @Override
    public DocumentParser createParser() {
        return new PdfParser();
    }
}

(3)抽象产品
// 抽象产品接口
public interface DocumentParser {
    void parse(String content);
}
(4)具体产品
// Word 文档解析器
public class WordParser implements DocumentParser {
    @Override
    public void parse(String content) {
        System.out.println("Parsing Word document: " + content);
    }
}

// PDF 文档解析器
public class PdfParser implements DocumentParser {
    @Override
    public void parse(String content) {
        System.out.println("Parsing PDF document: " + content);
    }
}
(5)客户端代码
public class Main {
    public static void main(String[] args) {
        // 使用工厂方法创建解析器
        ParserFactory wordFactory = new WordParserFactory();
        DocumentParser wordParser = wordFactory.createParser();
        wordParser.parse("This is a Word document");

        ParserFactory pdfFactory = new PdfParserFactory();
        DocumentParser pdfParser = pdfFactory.createParser();
        pdfParser.parse("This is a PDF document");
    }
}

工厂方法模式与简单工厂模式

特性简单工厂模式工厂方法模式
创建逻辑由单一工厂类负责,集中管理创建逻辑每个具体工厂负责创建特定类型的产品
扩展性修改工厂类即可扩展产品,但违反开闭原则添加新产品时只需添加新的工厂类,符合开闭原则
适用场景产品种类较少,变化不频繁产品种类较多,变化频繁,需要满足扩展性要求
类的复杂度工厂类单一,代码量少增加每种产品时需要增加对应的工厂类,类的数量较多
客户端与工厂的关系客户端依赖于具体的工厂类客户端依赖于抽象工厂,屏蔽具体实现细节

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

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

相关文章

【Linux】安装cuda

一、安装nvidia驱动 # 添加nvidia驱动ppa库 sudo add-apt-repository ppa:graphics-drivers/ppa sudo apt update# 查找推荐版本 sudo ubuntu-drivers devices# 安装推荐版本 sudo apt install nvidia-driver-560# 检验nvidia驱动是否安装 nvidia-smi 二、安装cudatoolkit&…

上天入地 灵途科技光电技术赋能空间感知

近来,人工智能技术频频亮相各大马拉松赛事,成为引人注目的科技亮点。 11月3日,杭州马拉松首次启用了机器狗作为配速员,以稳定的节奏为选手提供科学的跑步节奏。 11月11日,亦庄半程马拉松的终点处,人形机器…

Java三大特性:封装、继承、多态【详解】

封装 定义 隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读取和修改的访问级别便是封装。 在开发中造一个类就是封装,有时也会说封装一个类。封装可以隐藏一些细节或者包含数据不能被随意修改。 比如这是一个敏感的数据&a…

40分钟学 Go 语言高并发:【实战】并发安全的配置管理器(功能扩展)

【实战】并发安全的配置管理器(功能扩展) 一、扩展思考 分布式配置中心 实现配置的集中管理支持多节点配置同步实现配置的版本一致性 配置加密 敏感配置的加密存储配置的安全传输访问权限控制 配置格式支持 支持YAML、TOML等多种格式配置格式自动…

【ChatGPT大模型开发调用】如何获得 OpenAl API Key?

如何获取 OpenAI API Key 获取 OpenAI API Key 主要有以下三种途径: OpenAI 官方平台 (推荐): 开发者用户可以直接在 OpenAI 官方网站 (platform.openai.com) 注册并申请 API Key。 通常,您可以在账户设置或开发者平台的相关页面找到申请入口。 Azure…

苹果系统中利用活动监视器来终止进程

前言 苹果系统使用的时候总是感觉不太顺手。特别是转圈的彩虹球出现的时候,就非常令人恼火。如何找到一个像Windows那样任务管理器来终止掉进程呢? 解决办法 Commandspace 弹出搜索框吗,如下图: 输入“活动”进行搜索&#xff…

实战项目负载均衡式在线 OJ

> 作者:დ旧言~ > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:能自己实现负载均衡式在线 OJ。 > 毒鸡汤:有些事情,总是不明白,所以我不会坚持。早安! > 专栏选自&#xff1…

python Flask指定IP和端口

from flask import Flask, request import uuidimport json import osapp Flask(__name__)app.route(/) def hello_world():return Hello, World!if __name__ __main__:app.run(host0.0.0.0, port5000)

burp suite-1

声明! 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关&a…

【Spring boot】微服务项目的搭建整合swagger的fastdfs和demo的编写

文章目录 1. 微服务项目搭建2. 整合 Swagger 信息3. 部署 fastdfsFastDFS安装环境安装开始图片测试FastDFS和nginx整合在Storage上安装nginxnginx安装不成功排查:4. springboot 整合 fastdfs 的demodemo编写1. 微服务项目搭建 版本总结: spring boot: 2.6.13springfox-boot…

【区块链】深入理解椭圆曲线密码学(ECC)

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 深入理解椭圆曲线密码学(ECC)1. 概述2. 椭圆曲线的数学基础2.1 基本定义2.2 有限…

【Qt流式布局改造支持任意位置插入和删除】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、源代码二、删除代码三、扩展总结 前言 最近在做一个需求需要流式布局,虽然官方example里有一个流式布局范例,但是不能满足我的需求…

JQuery -- 第九课

文章目录 前言一、JQuery是什么?二、JQuery的使用步骤1.引入2.书写位置3. 表示方法 三、JQuery选择器1.层级选择器2. 筛选选择器3. 排他思想4. 精品展示 四、jQuery样式操作1. 修改样式2.类操作1. 添加2. 移除3. 切换 五、jQuery动画1. 显示和隐藏2. 滑动1. slide2.…

Python 版本的 2024详细代码

2048游戏的Python实现 概述: 2048是一款流行的单人益智游戏,玩家通过滑动数字瓷砖来合并相同的数字,目标是合成2048这个数字。本文将介绍如何使用Python和Pygame库实现2048游戏的基本功能,包括游戏逻辑、界面绘制和用户交互。 主…

在Elasticsearch中,是怎么根据一个词找到对应的倒排索引的?

大家好,我是锋哥。今天分享关于【在Elasticsearch中,是怎么根据一个词找到对应的倒排索引的?】面试题。希望对大家有帮助; 在Elasticsearch中,是怎么根据一个词找到对应的倒排索引的? 在 Elasticsearch 中…

C# 数据结构之【图】C#图

1. 图的概念 图是一种重要的数据结构,用于表示节点(顶点)之间的关系。图由一组顶点和连接这些顶点的边组成。图可以是有向的(边有方向)或无向的(边没有方向),可以是加权的&#xff…

Mac 系统上控制台常用性能查看命令

一、top命令显示 在macOS的控制台中,top命令提供了系统当前运行的进程的详细信息以及整体系统资源的利用情况。下面是对输出中各个字段的解释: Processes: 483 total: 系统上总共有483个进程。 2 running: 当前有2个进程正在运行。 481 sleeping: 当前有…

Docker--通过Docker容器创建一个Web服务器

Web服务器 Web服务器,一般指网站服务器,是驻留于因特网上某种类型计算机的程序。 Web服务器可以向浏览器等Web客户端提供文档,也可以放置网站文件以供全世界浏览,或放置数据文件以供全世界下载。 Web服务器的主要功能是提供网上…

Linux网络——NAT/代理服务器

一.NAT技术 1.NAT IP转换 之前我们讨论了, IPv4 协议中, IP 地址数量不充足的问题,NAT 技术就是当前解决 IP 地址不够用的主要手段, 是路由器的一个重要功能。 NAT 能够将私有 IP 对外通信时转为全局 IP. 也就是一种将私有 IP 和全局IP 相互转化的技术方法: 很…

极简开源Windows桌面定时提醒休息python程序

当我们长期在电脑面前坐太久后,会产生一系列健康风险,包括干眼症,颈椎,腰椎,肌肉僵硬等等。解决方案是在一定的时间间隔内我们需要have a break, 远眺可以缓解干眼症等眼部症状,站起来走动两步,…