当前位置: 首页 > news >正文

工厂模式和策略模式区别以及使用

工厂模式和策略模式是两种在软件设计中广泛使用的设计模式,它们各自具有独特的特点和适用场景。下面将详细阐述这两种模式的区别以及它们的使用方式。

一、工厂模式

定义与核心思想

工厂模式是一种创建型设计模式,其核心思想是将对象的创建与使用分离,以增加系统的灵活性和可维护性。在工厂模式中,客户端不需要直接实例化对象,而是通过调用一个共同的接口(或工厂类)来获取所需的对象实例。

主要类型

工厂模式主要包括简单工厂模式、工厂方法模式和抽象工厂模式。

  • 简单工厂模式:通过一个单独的工厂类来创建所有对象。这种模式虽然简单,但违背了开闭原则,因为每当新增产品时,都需要修改工厂类。
  • 工厂方法模式:将对象的创建延迟到子类中,由子类决定具体创建哪个对象。这种模式符合开闭原则,新增产品时只需添加相应的子类,无需修改现有代码。
  • 抽象工厂模式:提供一个接口,用于创建一系列相关或相互依赖的对象,而不需要指定具体的类。这种模式适用于需要创建一组相关对象的产品族时。
优点
  1. 解耦:将对象的创建与使用分离,降低了模块间的耦合度。
  2. 灵活性:客户端只需知道所需产品的抽象类型,无需知道具体实现类。
  3. 可扩展性:当需要新增产品时,工厂方法模式和抽象工厂模式可以通过添加新的子类或具体工厂类来实现,无需修改原有代码。
缺点
  • 简单工厂模式可能过于庞大,违背了单一职责原则。
  • 工厂方法模式和抽象工厂模式虽然解决了单一职责问题,但增加了类的数量,增加了系统的复杂度。
使用场景
  1. 当对象的创建逻辑较为复杂,或者需要根据不同的条件创建不同的对象时。
  2. 需要隐藏对象创建的细节,提高代码的封装性。
  3. 在实际开发中,如数据库连接、UI控件、文件处理、日志记录等场景都适合使用工厂模式。

二、策略模式

定义与核心思想

策略模式是一种行为型设计模式,它定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。策略模式的核心思想是将算法的实现与使用分离,客户端可以根据需要选择合适的算法。

结构

策略模式通常包含以下几个角色:

  • 策略接口(Strategy):定义了一个公共接口,所有的算法或行为都以这个接口为准。
  • 具体策略类(ConcreteStrategy):实现了策略接口的具体算法或行为。
  • 上下文环境类(Context):接受客户的请求,随后把请求委托给某一个具体策略类。
  • 客户端(Client):创建上下文环境对象,并设置具体的策略对象,然后执行算法。
优点
  1. 算法自由切换:可以在运行时动态地选择算法。
  2. 易于扩展:增加新的算法或策略时,只需增加相应的具体策略类,无需修改原有代码。
  3. 高内聚低耦合:每个策略类封装了具体的算法,减少了客户端与算法之间的耦合。
缺点
  1. 当策略类较多时,类的数量会显著增加,增加了系统的复杂度。
  2. 客户端需要了解所有策略,以便在运行时选择合适的策略。
使用场景
  1. 当一个系统需要在多种算法或策略中进行选择和切换时。
  2. 不同的策略之间具有相似性,只是具体的实现方式不同。
  3. 在实际开发中,如满减促销、返现促销、打折促销等场景都适合使用策略模式。

三、工厂模式和策略模式的区别

  1. 关注点不同
    • 工厂模式关注对象的创建过程,将对象的创建与使用分离。
    • 策略模式关注算法或行为的实现和选择,允许在运行时选择算法的行为。
  2. 结构不同
    • 工厂模式通常有一个工厂类(或接口),根据不同的条件创建不同的具体产品对象。
    • 策略模式包含多个策略类和一个环境类(上下文环境),环境类持有并使用策略对象。
  3. 使用场景不同
    • 工厂模式适用于对象的创建逻辑较为复杂,或者需要根据不同的条件创建不同的对象时。
    • 策略模式适用于系统需要在多种算法或策略中进行选择和切换时。
  4. 目的不同
    • 工厂模式的主要目的是降低对象创建的复杂性,提高系统的灵活性和可维护性。
    • 策略模式的主要目的是定义算法的多样性,让算法的变化独立于使用算法的客户。

综上所述,工厂模式和策略模式是两种在软件设计中非常重要的设计模式。它们各自具有独特的特点和适用场景,在实际开发中应根据具体需求选择合适的设计模式。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • STM32第十二节(中级篇):串口通信(第二节)——串口固件库函数以及串口发送和接收代码讲解
  • Nginx与Tomcat的区别
  • 计算机网络部分基础知识
  • 安全无忧!Windows7全补丁旗舰版:集成所有补丁!
  • 【HBZ分享】MYSQL的联合索引 与 覆盖索引
  • 【二叉树进阶】--- 根据二叉树创建字符串
  • LabVIEW光纤水听器闭环系统
  • 数据库服务器运维最佳实践
  • record 关键字
  • 内核源码定制修改模块化技术总结
  • 线程的概念
  • 基于inotif的文件同步备份
  • 服务器是什么?怎么选择适合自己的服务器?
  • 设计模式 - 组合模式
  • 百问网全志系列开发板音频ALSA配置步骤详解
  • Akka系列(七):Actor持久化之Akka persistence
  • canvas 绘制双线技巧
  • CSS 专业技巧
  • JAVA SE 6 GC调优笔记
  • javascript面向对象之创建对象
  • Lsb图片隐写
  • vagrant 添加本地 box 安装 laravel homestead
  • yii2中session跨域名的问题
  • 编写高质量JavaScript代码之并发
  • 动态魔术使用DBMS_SQL
  • 讲清楚之javascript作用域
  • 使用 Docker 部署 Spring Boot项目
  • 学习HTTP相关知识笔记
  • 最近的计划
  • 第二十章:异步和文件I/O.(二十三)
  • ​学习一下,什么是预包装食品?​
  • #php的pecl工具#
  • #预处理和函数的对比以及条件编译
  • $.ajax中的eval及dataType
  • (06)Hive——正则表达式
  • (7)svelte 教程: Props(属性)
  • (C++哈希表01)
  • (TOJ2804)Even? Odd?
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐
  • (七)Flink Watermark
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (五)IO流之ByteArrayInput/OutputStream
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (轉貼)《OOD启思录》:61条面向对象设计的经验原则 (OO)
  • .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地中转一个自定义的弱事件(可让任意 CLR 事件成为弱事件)
  • .Net插件开发开源框架
  • .NET和.COM和.CN域名区别
  • [ C++ ] STL priority_queue(优先级队列)使用及其底层模拟实现,容器适配器,deque(双端队列)原理了解
  • [ vulhub漏洞复现篇 ] GhostScript 沙箱绕过(任意命令执行)漏洞CVE-2019-6116
  • [APIO2015]巴厘岛的雕塑
  • [C#]使用C#部署yolov8的目标检测tensorrt模型