技术成神之路:设计模式(四)工厂方法模式

1.定义


工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它提供了一种创建对象的接口,而不是通过具体类来实例化对象。工厂方法模式的主要作用是让子类决定实例化哪一个类,从而实现对象创建的延迟到具体子类中进行。

2.主要作用


作用就是使设计更加灵活和可扩展。通过这种方式,父类无需知道具体要创建的对象是哪一种,这样就提高了系统的可扩展性和可维护性(符合开闭原则)一切优秀的模式都向设计原则看齐。

3.解决的问题

说到解决的问题,这里就不得不提下简单工厂模式了,什么?你不知道简单工厂模式是什么,没关系,先来看下定义:

简单工厂模式是一种创建型模式,它定义了一个工厂类,该类包含一个方法,根据给定的参数来返回不同类的实例。
客户端通过向工厂类传递参数来获取所需的具体对象实例,而不需要直接实例化对象。

包含角色:

  1. 工厂类(Factory):负责根据客户端的请求创建相应的对象。

  2. 产品类(Product):被创建的对象的基类或接口。具体的产品类是工厂类所创建的对象类型。

  3. 具体产品类(Concrete Product):实现了产品接口的具体对象类,由工厂类根据客户端的需求创建和返回。

UML类图:
在这里插入图片描述
代码示例:

public class LoggerFactory {
    public static Logger createLogger(String logType) {
        if ("Console".equals(logType)) {
            return new ConsoleLogger();
        } else if ("File".equals(logType)) {
            return new FileLogger();
        } else if ("Remote".equals(logType)) {
            return new RemoteLogger();
        } else {
            throw new IllegalArgumentException("Unsupported log type");
        }
    }
}

通过 LoggerFactory.createLogger("Console")LoggerFactory.createLogger("File") 或者 LoggerFactory.createLogger("Remote") 来获取不同类型的日志记录器,这种方式就是简单工厂模式,熟不熟悉,在你的项目中是不是也使用过这种模式呢,由于不难理解所以称为简单

简单是简单,当然他也有一些弊端,如果上面示例代码中 Logger 抽象类中只有打印一个方法,后续需要新增保存日志,过滤日志… 问题就暴露出来了,简单来说就是 简单工厂模式违反了开闭原则,即对扩展开放,对修改关闭

工厂方法模式解决了简单工厂模式的哪些问题?

  • 开闭原则:工厂方法模式遵循开闭原则,通过定义抽象工厂类和具体工厂类的继承关系,新增产品时只需增加具体工厂类和产品类,而无需修改现有代码,降低了系统的耦合性。
  • 扩展性:工厂方法模式支持更多的灵活性,每个具体的工厂类只负责创建对应的产品,符合单一职责原则,代码更加清晰和可维护。
  • 维护性:由于工厂方法模式将对象的创建延迟到子类中,避免了简单工厂模式中工厂类集中所有产品创建逻辑的问题,使代码结构更加清晰和可扩展。

简单来说,就是解决了简单工厂模式中集中创建逻辑和不符合开闭原则的问题,提高了代码的灵活性和可维护性。

4.模式原理

包含角色:

  1. 产品(Product):定义产品的接口。
  2. 具体产品(ConcreteProduct):实现产品接口的具体类。
  3. 工厂(Factory):定义创建产品对象的接口。
  4. 具体工厂(ConcreteFactory):实现创建产品对象的具体类。

UML类图:
在这里插入图片描述

// 定义产品接口
public interface Product {
    String operation();
}

// 定义具体产品类
public class ConcreteProductA implements Product {
    @Override
    public String operation() {
        return "产品A";
    }
}

public class ConcreteProductB implements Product {
    @Override
    public String operation() {
        return "产品B";
    }
}

// 定义工厂接口
public abstract class Creator {
    // 工厂方法
    public abstract Product factoryMethod();

    // 其它操作方法
    public String someOperation() {
        Product product = factoryMethod();
        return product.operation();
    }
}

// 定义具体工厂类
public class ConcreteCreatorA extends Creator {
    @Override
    public Product factoryMethod() {
        return new ConcreteProductA();
    }
}

public class ConcreteCreatorB extends Creator {
    @Override
    public Product factoryMethod() {
        return new ConcreteProductB();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        clientCode(new ConcreteCreatorA());
        clientCode(new ConcreteCreatorB());
    }

    public static void clientCode(Creator creator) {
        System.out.println("Client: " + creator.someOperation());
    }
}

打印:

Client: 产品A
Client: 产品B

相较简单工厂模式 增加了一个具体工厂角色,每增加一个具体产品,需要同时增加一个具体工厂类。所以说各有优缺点吧。

4.优缺点


优点:

  • 遵循开闭原则:可以在引入新产品时不修改现有代码。
  • 遵循单一职责原则:将产品对象的创建逻辑封装在工厂类中。
  • 减少代码耦合:客户端不直接依赖于具体类,只依赖于抽象产品和工厂接口(符合依赖倒置原则)。.

缺点:

  • 增加代码复杂性:每增加一个具体产品,需要同时增加一个具体工厂类。
  • 类的数量增加:每个具体产品都需要一个对应的具体工厂,会导致类的数量增加。

5.应用场景


  1. 需要创建复杂对象:当对象的创建过程比较复杂,且需要多步操作时。
  2. 产品种类多且类型不确定:当系统中需要创建的产品种类较多且类型在运行时才确定时。
  3. 需要对创建过程进行控制:当需要对对象的创建过程进行控制,并且希望将控制逻辑封装起来时。

emm… 其实还是简单工厂模式 应用场景更广泛些,毕竟简单好用🤭

总结比较:

  • 简单工厂模式适合于对象类型较少且不经常变化的场景,代码较为简单,但不符合开闭原则,难以扩展新的产品类型。
  • 工厂方法模式更加符合开闭原则,通过增加新的具体工厂和具体产品类来扩展系统功能,但会增加系统中类的个数和复杂度。

6.总结


工厂模式解决了简单工厂模式中集中创建逻辑和不符合开闭原则的问题,但同时自身也有一些弊端,但通过合理应用工厂方法模式,在特定的场景可以有效地提高系统的可维护性和扩展性。

设计模式没有最好的,只有最适合的,大家在选用时,要权衡利弊,避免过度设计!

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

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

相关文章

EE trade:千足金是什么意思

千足金(也称足金999、足999、au999等)是一种金含量不低于999‰的黄金,这意味着在一千克的千足金中,至少有999克是纯金。由于其极高的纯度,千足金在市场上比普通的足金价格略高,虽然价格差距可能仅为每克几元,但在大批量…

轴心轨迹的绘制(包含降噪前处理,MATLAB)

由于旋转机械振动波形的噪声干扰大,直接对振动数据特征提取和选择的故障诊断方法,其精度容易受到噪声影响。当前,基于图像的旋转机械故障诊断技术已经得到飞速的发展。针对旋转机械的故障诊断问题,传统方法趋向于从振动数据中提取…

springboot美食分享平台-计算机毕业设计源码45429

基于Web美食分享平台的系统设计与实现 摘 要 本研究基于Spring Boot框架,设计并实现了一个Web美食分享平台,旨在为用户提供一个交流分享美食体验的社区平台。该平台涵盖了用户注册登录、美食制作方法分享发布、点赞评论互动等功能模块,致力于…

精简库存,避免售罄 零售商常见错误及策略

减少库存是库存管理中最容易被误解和管理不善的策略之一。但如果正确执行,精简运营可以大幅降低成本,同时减少缺货和新鲜产品的损坏。 问题是什么?太多企业在尝试精简库存时陷入了同样的陷阱。不依赖过剩库存的库存规划能够提供所需的灵活性…

七款知名电脑监控软件的介绍(2024年电脑监控软件整理推荐)

在信息化迅猛发展的今天,电脑监控软件成为企业管理和安全防护的重要工具。这类软件不仅有助于提高员工工作效率,还能防范数据泄露,保障企业的核心利益。以下是对几款知名电脑监控软件的介绍,它们在各自领域内都有出色表现。 固信…

【MPPT太阳能升压控制器方案】远翔升压恒流驱动芯片FP7209单节电池升压24V,30V,36V,42V,48V全系列方案,高转换效率,输出带短路保护功能

高转换效率,太阳能控制器方案——详解太阳能控制器PWM / MPPT极简方案其设计要点,升压30V,36V,42V,48V 使用单颗芯片FP7209即实现两级升压到30V,36V,42V,48V,相对于单极升…

Linux_网络编程_TCP

服务器客户端模型: client / server brow / ser b / s http p2p socket——tcp 1、模式 C/S 模式 》服务器/客户端模型 server :socket()-->bind()--->listen()-->accept()-->recv()-->close()client :socket()-->conn…

isaac sim 与 WLS2 ros2实现通信

Omniverse以及isaac还是windows下使用顺手一点,但是做跟ros相关的开发时候,基本就得迁移到ubuntu下了,windows下ros安装还是过于复杂,那不想用双系统或者ubuntu或者虚拟机,有啥别的好方法呢?这里想到了wind…

pcie 基础

1. 传输速率与带宽的关系 当我们谈论PCIe总线标准的传输速率时,我们使用GT/s(Giga Transfers per second,千兆传输/秒)来衡量,而不是Gbps(Giga Bits Per Second,千兆位/秒)。这是因为…

高德地图 key 和安全密钥使用

参考高德地图:JS API 安全密钥使用 高德地图 key 和安全密钥使用 一、通过明文方式设置参数查看如下成功后返回的信息 二、通过代理服务器转发实验:通过本地地址转发返回错的错误信息,如下通过正确的项目的的服务地址,返回正常参数…

基于Netty的自研流系统缓存实现挑战: 内存碎片与OOM困境

01 前言 Kafka 作为流处理平台,在实时流计算和在线业务场景,追尾读追求端到端低延迟。在离线批处理和削峰填谷场景,数据冷读追求高吞吐。两个场景都需要很好的数据缓存设计来支撑,Apache Kafka 的数据存储在本地文件&#xff0c…

macos 10.15系统下载包,macOS Catalina for mac

macOS Catalina 让你喜欢的种种 Mac 体验都更进一步。你可以领略音乐、播客这两款全新 Mac app 的表演;在 Mac 上畅享各款自己心爱的 iPad app;拿起 iPad 和 Apple Pencil,拓展工作空间,释放创意灵感;再打开那些平时常…

无线麦克风什么牌子好,麦克风哪款好,口碑最好的k歌麦克风推荐

随着短视频和直播平台的流行,越来越多的人开始通过Vlog记录生活,并在此基础上开展副业。这种趋势推动了麦克风技术的快速发展,市场上出现了更多款式和功能各异的麦克风,以适应不同的视频创作需求。无线领夹麦克风因其便携性和实用…

【机器学习】必会数学知识:一文掌握数据科学核心数学知识点(下),收藏~

核心数学知识点 1、引言2、数据科学必会数学知识2.13 K均值聚类2.14 决策树2.15 随机森林2.16 梯度下降2.17 随机梯度下降(SGD)2.18 卷积2.19 拉普拉斯变换2.20 傅里叶变换2.21 信息论2.22 时间序列分析2.23 生成模型与判别模型2.24 支持向量机&#xff…

Centos7 安装Docker步骤及报错信息(不敢说最全,但是很全)

一、操作系统要求: 要安装Docker Engine,您需要CentOS 7及以上的维护版本。存档版本不受支持或测试。必须启用centos临时存储库。默认情况下,此存储库已启用,但如果已禁用,则需要重新启用它。建议使用overlay2存储驱动…

【JavaScript】深入理解Promise:从基础概念到进阶用法、手写promise

🔥 个人主页:空白诗 文章目录 一、引言二、Promise概述1. Promise的定义2. Promise的用途3. Promise的三种状态4. Promise的构造函数和基础结构5. Promise的优点6. Promise的实例方法7. Promise的静态方法 三、Promise的基本用法1. 创建一个Promise2. th…

【深度学习(42)】通过vscode使用anaconda的python环境

按ctrlshiftp,选择Python:Select Interpreter 选择anaconda下的python虚拟环境

亚马逊关键词优化全攻略:自养号测评让你的产品跃居首页

常常听到亚马逊运营吐槽: 为啥我的产品就是上不了首页呢? 我的关键词要怎么优化才能排名靠前啊? 的确,每天都有无数个卖家在想方设法让自己的产品排到首页,所以产品的竞争激烈程度不言而喻。 我们在亚马逊运营中&a…

3Ds MAX 2025:创意的翅膀

初识3Ds MAX 2025 在我初次接触3Ds MAX 2025时,仿佛打开了一扇通往无限可能的大门。那时,我还是一个对三维建模充满好奇的初学者,心中怀揣着对未来的憧憬和对艺术的热爱。3Ds MAX 2025的出现,如同一位温柔的导师,带领…

C语言学习笔记[23]:循环语句while①

C语言除了顺序结构和选择结构还有循环结构 whilefordo...while while循环 //while 语法结构 while(表达式)循环语句; 表达式的结果为真&#xff0c;则执行循环语句&#xff0c;否则循环停止 例如&#xff1a;打印1~10 #include <stdio.h>int main() {int i 1;whil…