工厂模式与策略模式:理解与应用

ops/2024/9/24 6:13:42/

工厂模式与策略模式:理解与应用

    • 1. 引言
    • 2. 工厂模式简介
      • 2.1 定义
      • 2.2 特点
      • 2.3 应用场景
      • 2.4 工厂模式例子:咖啡制作
    • 3. 策略模式简介
      • 3.1 定义
      • 3.2 特点
      • 3.3 应用场景
      • 3.4 策略模式例子:咖啡定价
    • 4. 区别
      • 4.1 目的不同
      • 4.2 应用场景不同
      • 4.3 解决问题不同
      • 4.4 设计原理不同
    • 5. 结论

在面向对象的设计中,工厂模式和策略模式是非常重要的两种设计模式。它们虽然有着不同的应用场景,但在很多方面都有一定的相似性,使得容易混淆。本文清晰地阐述这两种模式之间的区别,并探讨它们的应用场景。

1. 引言

工厂模式和策略模式都是广泛使用的模式,它们各自解决了不同层面的问题。接下来将分别介绍这两种模式的基本概念、特点以及应用场景。

2. 工厂模式简介

2.1 定义

工厂模式是一种创建型设计模式,它提供了创建对象的最佳方式。在工厂模式中,在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。工厂模式的核心思想是将对象的创建与使用分离,通过一个工厂类来负责创建产品族中的各种实例。

2.2 特点

  • 封装创建逻辑:工厂方法隐藏了具体的创建逻辑,使客户端无需关心创建过程。
  • 易于扩展:新增产品类型时只需添加相应的实现类和工厂类即可,符合开闭原则。
  • 解耦:客户端与具体的产品类解耦,只与抽象接口交互。

2.3 应用场景

  • 当类的实例只能由直接调用构造函数创建时,可以使用工厂模式来提供一个统一的创建入口。
  • 当一个类不知道它所必须创建的对象的确切类时。
  • 当一个类希望由它的子类指定它所创建的对象时。

2.4 工厂模式例子:咖啡制作

在这个例子中,工厂模式用于创建不同类型的咖啡。

// 咖啡接口
interface Coffee {void brew();
}
// 具体的咖啡类
class Espresso implements Coffee {@Overridepublic void brew() {System.out.println("制作浓缩咖啡");}
}class Latte implements Coffee {@Overridepublic void brew() {System.out.println("制作拿铁咖啡");}
}
// 咖啡工厂
class CoffeeFactory {public Coffee createCoffee(String type) {if ("espresso".equalsIgnoreCase(type)) {return new Espresso();} else if ("latte".equalsIgnoreCase(type)) {return new Latte();}throw new IllegalArgumentException("未知的咖啡类型");}
}
// 使用
public class CoffeeShop {public static void main(String[] args) {CoffeeFactory factory = new CoffeeFactory();Coffee espresso = factory.createCoffee("espresso");espresso.brew();  // 输出:制作浓缩咖啡Coffee latte = factory.createCoffee("latte");latte.brew();  // 输出:制作拿铁咖啡}
}

在这个例子中,工厂模式用于创建不同类型的咖啡对象。客户端只需要知道想要的咖啡类型,而不需要了解具体的咖啡类。

3. 策略模式简介

3.1 定义

策略模式是一种行为型设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。策略模式让算法独立于使用它的客户端。

3.2 特点

  • 灵活性策略模式允许在运行时选择算法。
  • 易于维护:每个策略都是独立的,易于理解和维护。
  • 减少条件分支:使用策略模式可以减少代码中的 if-else 或 switch-case 语句。

3.3 应用场景

  • 当一个系统需要根据不同条件执行不同的算法或行为时。
  • 当一个系统需要动态地更改其行为时。

3.4 策略模式例子:咖啡定价

使用策略模式来处理咖啡的定价策略。

// 定价策略接口
interface PricingStrategy {double calculatePrice(double basePrice);
}
// 具体的定价策略
class RegularPricing implements PricingStrategy {@Overridepublic double calculatePrice(double basePrice) {return basePrice;  // regular price, no discount}
}class DiscountPricing implements PricingStrategy {@Overridepublic double calculatePrice(double basePrice) {return basePrice * 0.9;  // 10% discount}
}class HappyHourPricing implements PricingStrategy {@Overridepublic double calculatePrice(double basePrice) {return basePrice * 0.5;  // 50% discount during happy hour}
}
// 咖啡订单类
class CoffeeOrder {private PricingStrategy pricingStrategy;private double basePrice;public CoffeeOrder(double basePrice) {this.basePrice = basePrice;this.pricingStrategy = new RegularPricing();  // 默认使用常规定价}public void setPricingStrategy(PricingStrategy pricingStrategy) {this.pricingStrategy = pricingStrategy;}public double getFinalPrice() {return pricingStrategy.calculatePrice(basePrice);}
}
// 使用
public class CoffeeShopPricing {public static void main(String[] args) {CoffeeOrder order = new CoffeeOrder(5.0);  // 咖啡基础价格为 $5System.out.println("Regular price: $" + order.getFinalPrice());order.setPricingStrategy(new DiscountPricing());System.out.println("Discounted price: $" + order.getFinalPrice());order.setPricingStrategy(new HappyHourPricing());System.out.println("Happy hour price: $" + order.getFinalPrice());}
}

在这个例子中,策略模式用于在运行时改变价格计算的方法。咖啡订单类可以动态地改变其定价策略,而无需修改订单类的代码。

4. 区别

尽管工厂模式和策略模式在某些方面相似,但它们之间还是存在明显的区别:

4.1 目的不同

  • 工厂模式:主要目的是创建对象实例,封装了对象创建的过程。
  • 策略模式:关注的是如何在运行时选择和替换算法。

4.2 应用场景不同

  • 工厂模式:适用于创建多种不同类型的对象。
  • 策略模式:适用于具有多种算法或行为的系统。

4.3 解决问题不同

  • 工厂模式:解决对象创建的问题。
  • 策略模式:解决算法或行为的选择和切换问题。

4.4 设计原理不同

  • 工厂模式:遵循开闭原则,通过抽象类或接口来实现。
  • 策略模式:通过组合而非继承来实现行为的改变。

5. 结论

工厂模式和策略模式都是设计模式的重要组成部分。工厂模式关注于对象的创建过程,而策略模式则关注于算法的选择与替换。理解它们之间的差异有助于在设计时做出合适的选择。



http://www.ppmy.cn/ops/99008.html

相关文章

开源模型应用落地-qwen2-7b-instruct-LoRA微调模型合并-Axolotl-单机单卡-V100(十)

一、前言 本篇文章将使用Axolotl去合并微调后的模型权重,通过阅读本文,您将能够更好地掌握这些关键技术,理解其中的关键技术要点,并应用于自己的项目中。 二、术语介绍 2.1. LoRA微调 LoRA (Low-Rank Adaptation) 用于微调大型语言模型 (LLM)。 是一种有效的自适应策略,…

easyexcel--导入导出实现自定义格式转换

自定义格式 我们在数据库设计的时候经常会有枚举类型,如0表示普通用户,1表示VIP用户等,这在excel导入的时候,我们会填普通用户而不是0,这样就需要用到自定义格式把普通用户转换成0,我写了一个通用的抽象类…

代码生成:自动化开发

在现代集成开发环境中,智能代码补全和代码生成功能是两个至关重要的组成部分。 智能代码补全利用当前上下文和代码库信息,向程序员推荐合适的代码选项,而代码生成则根据指定输入创建遵循语法和语义规范的代码片段。 许多先进的IDE如Visual St…

【linux中高级命令】

杀进程 1、lsof列出所有打开的文件,‌包括网络连接,‌从而提供关于系统状态的宝贵信息‌ #可以直接查看端口的进程 lsof -i:端口获取到进程,使用kill命令和PID来终止进程 kill -9 [PID]2、列出使用该端口的进程信息,‌包括PID …

UniApp中的Flex布局技巧

随着移动互联网的迅速发展,越来越多的开发者开始使用跨平台技术来开发应用程序。而在跨平台开发里,uniapp是一种非常受欢迎的框架,由于使用uniapp可以快速地开发出同时支持多个平台的应用程序。在uniapp开发中,flex布局是一种非常…

SpringBoot教程(二十五) | SpringBoot整合Sharding-JDBC分库分表

SpringBoot整合Sharding-JDBC分库分表 前言1. 什么是Sharding?2. 什么是Sharding-JDBC? 所需的maven依赖注意点(关于shardingsphere的配置情况)实操一:如何水平分表1. 步骤说明2. 创建数据库和表3.配置application.pro…

xcode如何编译python

1、找到Python位置: 终端输入:which python 获取python的安装位置,一般为/usr/bin/python。获取到这个路径方便使用它来搭建python的编译环境。 2、在Xcode中创建python程序 打开Xcode,新建工程(ShiftCommandN&…

Can‘t load tokenizer for ‘bert-base-uncased‘

先下载https://storage.googleapis.com/bert_models/2020_02_20/uncased_L-12_H-768_A-12.zip 我上传了一个:https://download.csdn.net/download/LEE18254290736/89652982?spm1001.2014.3001.5501 下载完了解压缩。 之后在项目工程新建一个文件夹,命名…