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

【设计模式】实际场景解释策略模式与工厂模式的应用

文章目录

  • 前言
  • 策略模式
    • 概念
    • 场景
    • 示例
  • 工厂模式
    • 概念
    • 场景
    • 示例
  • 策略模式与工厂模式的比较
    • 相同点
    • 不同点
  • 总结

前言

策略模式和工厂模式是常见的设计模式,它们可以帮助我们更好地组织和管理代码,提高代码的可维护性和可扩展性。

在本篇博客中,我将使用Java和SpringBoot作为示例,详细讲解策略模式和工厂模式的概念、场景和示例,并且帮助读者更好地理解它们的异同。

更多设计模式可以参考之前我写的文章:谈谈我们工作中的23个设计模式

策略模式

概念

  • 策略模式是一种行为设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以互换
  • 策略模式可以让算法独立于使用它们的客户端而变化
  • 通俗来讲,策略模式就是将一组算法封装起来,让它们可以相互替换,从而使得算法可以独立于客户端而变化。

场景

策略模式通常应用于以下场景:

  • 在一个系统中需要多个算法,并且这些算法经常需要切换。
  • 当一个算法有多个变体,这些变体可以作为算法的一种实现。
  • 当一个算法需要在运行时动态地选择实现。

示例

假设我们有一个购物车系统,其中有一个结算功能。
结算功能的具体实现有两种,一种是普通会员结算,另一种是VIP会员结算。

我们可以使用策略模式来实现这个功能。

  • 具体实现如下:
    • 首先,我们定义一个结算策略接口:

      public interface SettlementStrategy {public double calculate(double price);
      }
      
    • 然后,我们实现两个具体的结算策略类,分别是普通会员结算和VIP会员结算:

      //普通会员
      public class NormalSettlementStrategy implements SettlementStrategy {@Overridepublic double calculate(double price) {return price;}
      }
      //VIP会员,九折
      public class VipSettlementStrategy implements SettlementStrategy {@Overridepublic double calculate(double price) {return price * 0.9;}
      }
      
    • 最后,我们在结算功能中使用策略模式来实现:

      public class ShoppingCart {private SettlementStrategy settlementStrategy;public void setSettlementStrategy(SettlementStrategy settlementStrategy) {this.settlementStrategy = settlementStrategy;}public double calculatePrice(double price) {return settlementStrategy.calculate(price);}
      }
      
    • 这样,我们就可以动态地选择结算策略了。具体使用方法如下:

      ShoppingCart shoppingCart = new ShoppingCart();
      // 使用普通会员结算策略
      shoppingCart.setSettlementStrategy(new NormalSettlementStrategy()); 
      // 结算100元
      double price = shoppingCart.calculatePrice(100); 
      

工厂模式

概念

  • 工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式,将对象的创建和使用分离开来
  • 工厂模式通常通过一个工厂类来创建对象,这样可以将对象的创建和具体实现分离,从而提高代码的可维护性和可扩展性。

场景

工厂模式通常应用于以下场景:

  • 当一个系统需要独立于它所使用的对象的创建、组合和表示时。
  • 当一个系统需要灵活地配置一组对象,并且需要动态地选择其中的一个时。
  • 当一个系统需要使用多个实例化类中的一个时,并且系统只知道这些类的接口时。

示例

假设我们有一个图形绘制系统,其中有一个绘制图形的功能。图形有三种类型,分别是圆形、正方形和矩形。

我们可以使用工厂模式来实现这个功能。

  • 具体实现如下:
    • 首先,我们定义一个图形接口:

      public interface Shape {public void draw();
      }
      
    • 然后,我们实现三个具体的图形类,分别是圆形、正方形和矩形:

      public class Circle implements Shape {@Overridepublic void draw() {System.out.println("Draw a circle");}}public class Square implements Shape {@Overridepublic void draw() {System.out.println("Draw a square");}}public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Draw a rectangle");}}
      
    • 最后,我们实现一个图形工厂类,用于创建图形对象:

      public class ShapeFactory {public static Shape getShape(String shapeType) {if (shapeType == null) {return null;} else if (shapeType.equalsIgnoreCase("circle")) {return new Circle();} else if (shapeType.equalsIgnoreCase("square")) {return new Square();} else if (shapeType.equalsIgnoreCase("rectangle")) {return new Rectangle();}return null;}
      }
      
    • 这样,我们就可以通过工厂类来创建图形对象了。具体使用方法如下:

      Shape circle = ShapeFactory.getShape("circle"); // 创建一个圆形对象
      circle.draw(); // 绘制圆形Shape square = ShapeFactory.getShape("square"); // 创建一个正方形对象
      square.draw(); // 绘制正方形Shape rectangle = ShapeFactory.getShape("rectangle"); // 创建一个矩形对象
      rectangle.draw(); // 绘制矩形
      

策略模式与工厂模式的比较

策略模式和工厂模式都是常见的设计模式,它们在实现上有很多相似之处,但也有一些不同之处。

相同点

  • 都是用于解耦对象的创建和使用。
  • 都可以提高代码的可维护性和可扩展性。
  • 都可以动态地选择实现。

不同点

  • 策略模式是用于封装一组算法,让它们可以互相替换,而工厂模式是用于创建对象。

  • 策略模式是面向对象的实现,它通过将算法封装成一个对象来实现,而工厂模式是一种创建型模式,它通过一个工厂类来创建对象。

  • 策略模式主要关注的是算法的不同实现,而工厂模式主要关注的是对象的创建过程。

  • 策略模式中的具体算法可以通过工厂模式来创建。

总结

策略模式和工厂模式都是常见的设计模式,它们在解耦对象的创建和使用方面有很好的效果。

  • 策略模式可以使算法的实现互相替换,从而提高系统的灵活性和可维护性;
  • 工厂模式可以将对象的创建和具体实现分离,从而提高代码的可维护性和可扩展性。

在实际应用中,我们可以根据具体的需求来选择适合的设计模式。

相关文章:

【设计模式】实际场景解释策略模式与工厂模式的应用

文章目录 前言策略模式概念场景示例 工厂模式概念场景示例 策略模式与工厂模式的比较相同点不同点 总结 前言 策略模式和工厂模式是常见的设计模式,它们可以帮助我们更好地组织和管理代码,提高代码的可维护性和可扩展性。 在本篇博客中,我将…...

外包干了三年,算是废了...

先说一下自己的情况。大专生,19年通过校招进入湖南某软件公司,干了接近3年的测试,今年年上旬,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了三年&#xff0c…...

九龙证券|光模块概念股封单资金超3亿元,传媒板块涨停潮来袭

今天A股三大股指低开低走。沪深两市收盘共37股涨停。剔除4只ST股,合计33股涨停。另外,10股封板未遂,整体封板率为78.72%。 涨停战场: 华工科技封单资金超3亿元 从收盘涨停板封单量来看,同方股份封单量最高&#xff0…...

[ES6] 数组

[ES6] 数组 数组的创建类数组对象可迭代对象的转换 扩展方法findfindIndexfillcopyWithinentrieskeysvaluesincludesflatflatMap 扩展运算符复制数组合并数组 数组缓冲区创建数组缓冲区视图创建 定型数组创建通过数组缓冲区生成通过构造函数 定型数组特性 拷贝浅拷贝深拷贝 数组…...

【问题描述】编写一个程序计算出球、圆柱和圆锥的表面积和体积。

【问题描述】 编写一个程序计算出球、圆柱和圆锥的表面积和体积。 要求: (1)定义一个基类,至少含有一个数据成员半径,并设为保护成员; (2)定义基类的派生类球、圆柱、圆锥&#…...

Python 人工智能:16~20

原文:Artificial Intelligence with Python 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自【ApacheCN 深度学习 译文集】,采用译后编辑(MTPE)流程来尽可能提升效率。 不要担心自己的形象,只关心如何…...

【华为OD机试真题】最优资源分配(javapython)

最优资源分配 知识点数组贪心Q时间限制:1s空间限制:32MB限定语言:不限 题目描述: 某块业务芯片最小容量单位为1.25G,总容量为M1.25G,对该芯片资源编号为1,2,…,M。该芯片支持3种不同的配置,分别为A、B、C。 配置A:占用容量为1.251=1.25G 配置B:占用容量为1.252=2…...

git的使用——操作流程

一、什么是git git是一个开源的分布式版本控制软件,能够有效并高效的处理很小到非常大的项目。 二、添加SSH公钥 安装下载后,会发现鼠标右击,会出现 Git Bash Here 这个选项,如图所示,点击进入 1.打开git窗口后&…...

Ae:自动定向

Ae 菜单:图层/变换/自动定向 Auto-Orient 快捷键:Ctrl Alt O 自动定向 Auto-Orient是 Ae 图层中的一个附加的、隐藏实现(不会在时间轴面板上更改属性的值)的功能,它可以使得图层自动旋转或改变方向以朝向指定的运动路…...

ClickHouse入门详解

ClickHouse基础部分详解 一、ClickHouse简介二、ClickHouse单机版安装2.1、ClickHouse安装前准备环境2.2、ClickHouse单机安装2.3、ClickHouse一些默认路径2.4、ClickHouse端口说明 三、ClickHouse数据类型四、ClickHouse的表引擎4.1 MergeTree4.1.1 partition by 分区 五、Cli…...

javaweb笔记2

JSP 1、在webapp的根目录下新建一个index.jsp文件,访问以下地址: http://localhost:8080/webappName/index.jsp 实际上访问这个index.jsp文件,底层执行的是:index_jsp.class这个程序。 这个index.jsp会被tomcat翻译成index_jsp.j…...

【IIS搭建网站】本地电脑做服务器搭建web站点并公网访问「内网穿透」

文章目录 1.前言2.Windows网页设置2.1 Windows IIS功能设置2.2 IIS网页访问测试 3. Cpolar内网穿透3.1 下载安装Cpolar3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5.结语 1.前言 在网上各种教程和介绍中,搭建网页都会借助各种软件的帮助,比如…...

算法训练day2:哈希表

哈希表理论基础 哈希表是根据关键码的值而直接进行访问的数据结构。 当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。 但是哈希法也是牺牲了空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据&#…...

Git——利用SSH密钥本地仓库上传远程GitHub库

文章目录 1、前言2、详细步骤2.1 创建密钥2.2 进入密钥文件并复制2.3 在GitHub上添加密钥2.4 回到本地仓库文件夹,连接GitHub并上传 3. 结语 1、前言 现在想要从本地设备将本地仓库上传到GitHub上需要用到SSH密钥,接下来讲解大致的步骤,本文默…...

一起读源码 —— Fastjson 的核心方法及其实现原理

源码介绍 Fastjson 是阿里巴巴开源的一个 Java 工具库,它常常被用来完成 Java 的对象与 JSON 格式的字符串的相互转化。 此文读的源码是撰写此文时 Fastjson 的最新的发布版本,即 1.2.83 下载源码 请前去 github 找到 release 最新版下载后解压&…...

Python实现批量图片下载及去重处理

背景 在爬虫应用开发中,常常需要批量下载图片,并对图片进行去重处理。Python 是一种非常流行的编程语言,也是开发爬虫应用的首选,本文将介绍如何使用 Python 下载图片,并对下载的图片进行去重处理。 内容 首先&…...

【QA】Python代码调试之解决Segmentation fault (core dumped)问题

Python代码调试之解决Segmentation fault 问题 问题描述排查过程1. 定位错误,2. 解决办法 参考资料 问题描述 Python3执行某一个程序时,报Segmentation fault (core dumped)错,且没有其他任何提示,无法查问题。 Segmentation fa…...

C++ 迭代器之旅(Journey of Iterators)

C 迭代器之旅(Journey of Iterators) 一、引言(Introduction)C Iterator模板库简介(Overview of C Iterator Template Library)Iterator的重要性和作用(The Importance and Role of Iterators&a…...

使用全球融合CDN的10大优势

根据预估,今年的全球内容交付网络(CDN)市场预计将达到424亿美元。而由于移动应用程序的激增和人工智能尤其是ChatGPT等相关领域的快速发展将进一步带来CDN市场的快速增长,可以说全球CDN的黄金时代才刚开始。 融合CDN和多CDN战略是…...

前端学习:HTML图像、表格、列表

目录 图像 一、图像标签和源属性(Src) 二、替换文本属性(Alt) 三、设置图片样式基本属性 四、图像标签 表格 一、标签 补充: 二、表格的表头 三、表格常用标签和属性 标签 属性 列表 一、无序列表 二、有序列表 三、定义列表 四、列表常用标签属性 图像 一、…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...

GitHub 趋势日报 (2025年06月08日)

📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求&#xff…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found"​, "n…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具&#xff0c;用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中&#xff0c;cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...