设计模式详解(十):策略模式——Strategy

ops/2024/12/16 5:17:31/

什么是Strategy设计模式

Strategy模式是一种行为型设计模式,它定义了一系列算法,将每种算法封装到独立的类中,使它们可以互换。使用该模式,可以在不修改客户端代码的情况下动态地改变算法的行为。

为什么需要Strategy模式?

  • 避免代码重复:在同一个类中包含多种算法会导致代码膨胀,Strategy模式通过分离不同的算法解决了这一问题。
  • 提高扩展性:可以轻松地添加新的算法,而无需修改现有代码。
  • 遵循开闭原则:通过封装算法,使得类对扩展开放,对修改关闭。

UML图解

下面是Strategy模式的通用UML图解:

Context
- strategy: Strategy
+setStrategy(strategy: Strategy)
+executeStrategy()
«interface»
Strategy
+execute()
ConcreteStrategyA
+execute()
ConcreteStrategyB
+execute()

实现示例

以下是一个简单的例子,展示如何使用Strategy模式实现不同的折扣策略。

定义策略接口
public interface DiscountStrategy {double calculateDiscount(double price);
}
实现具体策略

满减折扣策略:

public class FullReductionStrategy implements DiscountStrategy {@Overridepublic double calculateDiscount(double price) {if (price > 100) {return price - 20;}return price;}
}

百分比折扣策略:

public class PercentageDiscountStrategy implements DiscountStrategy {@Overridepublic double calculateDiscount(double price) {return price * 0.9;}
}
上下文类
public class ShoppingCart {private DiscountStrategy discountStrategy;public void setDiscountStrategy(DiscountStrategy discountStrategy) {this.discountStrategy = discountStrategy;}public double calculatePrice(double price) {if (discountStrategy == null) {throw new IllegalStateException("Discount strategy not set");}return discountStrategy.calculateDiscount(price);}
}
客户端代码
public class Main {public static void main(String[] args) {ShoppingCart cart = new ShoppingCart();// 使用满减策略cart.setDiscountStrategy(new FullReductionStrategy());System.out.println("满减后价格: " + cart.calculatePrice(120));// 使用百分比折扣策略cart.setDiscountStrategy(new PercentageDiscountStrategy());System.out.println("折扣后价格: " + cart.calculatePrice(120));}
}

流程图

以下是Strategy模式的执行流程:

Context设置Strategy
调用executeStrategy方法
执行具体Strategy中的方法
返回结果

优点

  1. 清晰的职责分离:每种算法被封装在独立的类中。
  2. 易于扩展:可以随时添加新的策略。
  3. 可维护性强:更改某种策略只需修改对应的策略类,不影响其他部分。

缺点

  1. 类数量增加:每种策略都需要单独的类,可能导致类的数量膨胀。
  2. 客户端需要理解不同的策略:客户端代码需要知道何时使用何种策略。

适用场景

  • 系统需要动态地在多个算法中选择其一。
  • 不同的客户需要不同的业务规则处理。
  • 避免使用条件语句将多个算法硬编码在一个类中。

总结

Strategy模式是解决算法或行为动态切换的有效方法。它通过将算法抽象化,使得代码更加灵活、易于扩展,同时也减少了代码重复。如果你在开发过程中遇到了需要频繁修改或扩展算法的需求,不妨考虑使用Strategy模式。


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

相关文章

java+springboot+mysql宠物网乐园(宠物论坛+宠物领养)

项目介绍: 使用javaspringbootmysql开发的宠物乐园网,一个集宠物论坛和宠物领养平台,系统包含超级管理员、管理员、用户角色,功能如下: 超级管理员:管理员管理;用户管理;帖子管理&…

反转链表 II

题解: /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* reverseBetween(struct ListNode* head, int left, int right) {struct ListNode* dummy(struct ListNode*)malloc(sizeof(…

Python 单例模式工厂模式和classmethod装饰器

前言: Python作为面向对象的语言,显然支持基本的设计模式。也具备面向对象的语言的基本封装方法:属性、方法、继承、多态等。但是,做为强大的和逐渐发展的语言,python也有很多高级的变种方法,以适应更多的…

Oracle PDB的开启和关闭

[生产环境关闭与开启Oracle PDB] 【运维场景】 在运维Oracle PDB的时候经常要开启和关闭PDB,对关闭和开启PDB的操作要非常熟悉。 【操作方法】 1. PDB的打开与关闭 关闭和开启DB的时候要看DB的警告日志,日志位置(在Oracle用户下查看&…

代码随想录第45天

115.不同的子序列 class Solution:def numDistinct(self, s: str, t: str) -> int:n1 len(s)n2 len(t)dp [[0] * (n1 1) for _ in range(n2 1)]for j in range(n1 1):dp[0][j] 1for i in range(1, n2 1):for j in range(1, n1 1):if t[i - 1] s[j - 1]:dp[i][j]…

ArcGIS字符串补零与去零

我们有时候需要 对属性表中字符串的补零与去零操作 我们下面直接视频教学 下面看视频教学 ArcGIS字符串去零与补零 推荐学习 ArcGIS全系列实战视频教程——9个单一课程组合 ArcGIS10.X入门实战视频教程(GIS思维) ArcGIS之模型构建器(Mod…

数据结构和算法-06线段树-01

线段树 什么是线段树 线段树是一种**[二叉搜索树]**,与[**区间树]**相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树的一个结点 [Segment Tree] is a data structure that stores data about range of elements in nodes as a …

etcd节点扩/缩容

etcd集群节点数量的说明 etcd 是基于 raft算法的分布式键值数据库,生来就为集群化而设计的,由于Raft算法在做决策时需要超半数节点的投票,所以etcd集群一般推荐奇数节点,如3、5或者7个节点构成一个集群。 对于具有 n 个成员的集群…