策略模式:算法切换的超级武器[特殊字符],让代码灵活如风!
·
策略模式:算法切换的超级武器🚀,让代码灵活如风!
前言:为什么需要策略模式?🤔
各位宝子们,今天我们来聊一个设计模式界的"算法大师"——策略模式!😎 还在为大量的if-else判断而头疼吗?还在为算法的频繁变更而烦恼吗?策略模式来拯救你啦!
策略模式是设计模式家族中的"行为型专家",它能帮我们优雅地管理算法族,让代码更加灵活、可扩展。今天就带大家彻底搞懂这个"看似简单,实则强大"的设计模式!💯
一、策略模式:算法切换的专业户 🎯
1.1 什么是策略模式?
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,把它们一个个封装起来,并且使它们可相互替换。就像现实生活中的出行方式一样,你可以选择步行、骑车、开车或坐地铁,每种方式都是一种策略,你可以根据情况灵活选择!🚗
1.2 为什么需要策略模式?
想象一下这些场景:
- 需要在运行时动态选择算法
- 有多种方式实现同一个功能
- 避免使用大量的条件判断语句
- 需要隐藏算法的具体实现细节
- 算法经常变化,需要易于扩展
这些场景有什么共同点?它们都涉及到算法的选择和切换问题。策略模式就是为这些场景量身定制的!🚀
二、策略模式的结构与实现 🧩
2.1 策略模式的核心结构
策略模式包含以下几个关键角色:
- 策略接口(Strategy):定义所有具体策略的通用接口
- 具体策略(ConcreteStrategy):实现策略接口的具体算法
- 上下文(Context):持有一个策略的引用,并将工作委托给策略对象
// 策略接口
public interface Strategy {
int execute(int a, int b);
}
// 具体策略:加法
public class AddStrategy implements Strategy {
@Override
public int execute(int a, int b) {
System.out.println("执行加法运算");
return a + b;
}
}
// 具体策略:减法
public class SubtractStrategy implements Strategy {
@Override
public int execute(int a, int b) {
System.out.println("执行减法运算");
return a - b;
}
}
// 具体策略:乘法
public class MultiplyStrategy implements Strategy {
@Override
public int execute(int a, int b) {
System.out.println("执行乘法运算");
return a * b;
}
}
// 上下文
public class Calculator {
private Strategy strategy;
public Calculator(Strategy strategy) {
this.strategy = strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public int calculate(int a, int b) {
return strategy.execute(a, b);
}
}
// 客户端代码
Calculator calculator = new Calculator(new AddStrategy());
int result1 = calculator.calculate(10, 5); // 输出:执行加法运算,结果:15
calculator.setStrategy(new MultiplyStrategy());
int result2 = calculator.calculate(10, 5); // 输出:执行乘法运算,结果:50
2.2 策略模式的工作流程
- 客户端创建具体策略对象
- 将策略对象传递给上下文
- 上下文将工作委托给策略对象
- 策略对象执行具体算法
- 可以在运行时动态切换策略
三、策略模式的实际应用案例 🌟
3.1 支付系统
电商系统中的支付方式选择是策略模式的经典应用。用户可以选择支付宝、微信、银行卡等不同的支付方式。
// 支付策略接口
public interface PaymentStrategy {
boolean pay(double amount);
String getPaymentType();
}
// 支付宝支付策略
public class AlipayStrategy implements PaymentStrategy {
private String account;
public AlipayStrategy(String account) {
this.account = account;
}
@Override
public boolean pay(double amount) {
System.out.println("使用支付宝账户 " + account + " 支付 " + amount + " 元");
// 模拟支付逻辑
return true;
}
@Override
public String getPaymentType() {
return "支付宝";
}
}
// 微信支付策略
public class WechatPayStrategy implements PaymentStrategy {
private String openId;
public WechatPayStrategy(String openId) {
this.openId = openId;
}
@Override
public boolean pay(double amount) {
System.out.println("使用微信账户 " + openId + " 支付 " + amount + " 元");
// 模拟支付逻辑
return true;
}
@Override
public String getPaymentType() {
return "微信支付";
}
}
// 银行卡支付策略
public class BankCardStrategy implements PaymentStrategy {
private String cardNumber;
private String cvv;
public BankCardStrategy(String cardNumber, String cvv) {
this.cardNumber = cardNumber;
this.cvv = cvv;
}
@Override
public boolean pay(double amount) {
System.out.println("使用银行卡 " + cardNumber + " 支付 " + amount + " 元");
// 模拟支付逻辑
return true;
}
@Override
public String getPaymentType() {
return "银行卡";
}
}
// 支付上下文
public class PaymentContext {
private PaymentStrategy paymentStrategy;
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public boolean executePayment(double amount) {
if (paymentStrategy == null) {
System.out.println("请选择支付方式");
return false;
}
System.out.println("选择的支付方式:" + paymentStrategy.getPaymentType());
return paymentStrategy.pay(amount);
}
}
// 使用示例
PaymentContext paymentContext = new PaymentContext();
// 使用支付宝支付
paymentContext.setPaymentStrategy(new AlipayStrategy("user@alipay.com"));
paymentContext.executePayment(100.0);
// 切换到微信支付
paymentContext.setPaymentStrategy(new WechatPayStrategy("wx123456"));
paymentContext.executePayment(200.0);
3.2 排序算法选择
根据数据量的大小选择不同的排序算法,这也是策略模式的典型应用。
// 排序策略接口
public interface SortStrategy {
void sort(int[] array);
String getAlgorithmName();
}
// 冒泡排序策略
public class BubbleSortStrategy implements SortStrategy {
@Override
public void sort(int[] array) {
System.out.println("使用冒泡排序");
int n = array.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (array[j] > array[j + 1]) {
// 交换元素
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
}
@Override
public String getAlgorithmName() {
return "冒泡排序";
}
}
// 快速排序策略
public class QuickSortStrategy implements SortStrategy {
@Override
public void sort(int[] array) {
System.out.println("使用快速排序");
quickSort(array, 0, array.length - 1);
}
private void quickSort(int[] array, int low, int high) {
if (low < high) {
int pi = partition(array, low, high);
quickSort(array, low, pi - 1);
quickSort(array, pi + 1, high);
}
}
private int partition(int[] array, int low, int high) {
int pivot = array[high];
int i = (low - 1);
for (int j = low; j < high; j++) {
if (array[j] <= pivot) {
i++;
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
int temp = array[i + 1];
array[i + 1] = array[high];
array[high] = temp;
return i + 1;
}
@Override
public String getAlgorithmName() {
return "快速排序";
}
}
// 排序上下文
public class SortContext {
private SortStrategy sortStrategy;
public void setSortStrategy(SortStrategy sortStrategy) {
this.sortStrategy = sortStrategy;
}
public void performSort(int[] array) {
if (sortStrategy == null) {
System.out.println("请选择排序算法");
return;
}
System.out.println("选择的排序算法:" + sortStrategy.getAlgorithmName());
long startTime = System.currentTimeMillis();
sortStrategy.sort(array);
long endTime = System.currentTimeMillis();
System.out.println("排序完成,耗时:" + (endTime - startTime) + "ms");
}
// 智能选择排序算法
public void smartSort(int[] array) {
if (array.length < 100) {
setSortStrategy(new BubbleSortStrategy());
} else {
setSortStrategy(new QuickSortStrategy());
}
performSort(array);
}
}
3.3 促销活动策略
电商系统中的促销活动也是策略模式的好例子,不同的促销策略可以灵活切换。
// 促销策略接口
public interface PromotionStrategy {
double calculateDiscount(double originalPrice);
String getPromotionName();
}
// 满减策略
public class FullReductionStrategy implements PromotionStrategy {
private double threshold;
private double reduction;
public FullReductionStrategy(double threshold, double reduction) {
this.threshold = threshold;
this.reduction = reduction;
}
@Override
public double calculateDiscount(double originalPrice) {
if (originalPrice >= threshold) {
return originalPrice - reduction;
}
return originalPrice;
}
@Override
public String getPromotionName() {
return "满" + threshold + "减" + reduction;
}
}
// 打折策略
public class DiscountStrategy implements PromotionStrategy {
private double discountRate;
public DiscountStrategy(double discountRate) {
this.discountRate = discountRate;
}
@Override
public double calculateDiscount(double originalPrice) {
return originalPrice * discountRate;
}
@Override
public String getPromotionName() {
return (int)((1 - discountRate) * 10) + "折";
}
}
// 促销上下文
public class PromotionContext {
private PromotionStrategy promotionStrategy;
public void setPromotionStrategy(PromotionStrategy promotionStrategy) {
this.promotionStrategy = promotionStrategy;
}
public double calculateFinalPrice(double originalPrice) {
if (promotionStrategy == null) {
System.out.println("无促销活动,原价销售");
return originalPrice;
}
double finalPrice = promotionStrategy.calculateDiscount(originalPrice);
System.out.println("促销活动:" + promotionStrategy.getPromotionName());
System.out.println("原价:" + originalPrice + ",优惠后:" + finalPrice);
return finalPrice;
}
}
四、策略模式的优缺点 ⚖️
4.1 优点
- 算法可以自由切换:可以在运行时动态选择算法
- 避免使用多重条件判断:消除大量的if-else或switch-case语句
- 扩展性良好:增加新算法只需要实现策略接口
- 符合开闭原则:对扩展开放,对修改关闭
- 提高算法的保密性和安全性:算法实现细节被封装
4.2 缺点
- 策略类数量增多:每个算法都需要一个策略类
- 客户端必须知道所有策略:客户端需要了解各种策略的区别
- 增加了对象的数目:每个策略都是一个对象
五、策略模式与其他模式的区别 🔍
5.1 策略模式 vs 状态模式
虽然结构相似,但意图不同:
- 策略模式:关注算法的互换,客户端主动选择策略
- 状态模式:关注对象状态的变化,状态转换通常是自动的
5.2 策略模式 vs 工厂模式
- 策略模式:关注算法的选择和执行
- 工厂模式:关注对象的创建
5.3 策略模式 vs 命令模式
- 策略模式:封装算法,关注"怎么做"
- 命令模式:封装请求,关注"做什么"
六、何时使用策略模式?🎯
以下场景适合使用策略模式:
- 需要在运行时动态选择算法
- 有多种方式实现同一个功能
- 存在大量的条件判断语句
- 算法经常变化,需要易于扩展
- 需要隐藏算法的实现细节
七、策略模式的最佳实践 💡
7.1 结合工厂模式
// 策略工厂
public class StrategyFactory {
private static final Map<String, PaymentStrategy> strategies = new HashMap<>();
static {
strategies.put("alipay", new AlipayStrategy("default@alipay.com"));
strategies.put("wechat", new WechatPayStrategy("default_openid"));
strategies.put("bankcard", new BankCardStrategy("1234567890", "123"));
}
public static PaymentStrategy getStrategy(String type) {
return strategies.get(type.toLowerCase());
}
}
7.2 使用枚举实现策略
public enum CalculationStrategy {
ADD {
@Override
public int execute(int a, int b) {
return a + b;
}
},
SUBTRACT {
@Override
public int execute(int a, int b) {
return a - b;
}
},
MULTIPLY {
@Override
public int execute(int a, int b) {
return a * b;
}
};
public abstract int execute(int a, int b);
}
总结:策略模式的精髓 💎
策略模式的核心思想是将算法的定义、创建和使用分离。这种设计使得我们可以:
- 在运行时动态选择算法
- 避免复杂的条件判断逻辑
- 轻松扩展新的算法
- 提高代码的可维护性和可测试性
策略模式就像是给程序安装了一个"算法切换器",让你能够根据不同的情况选择最合适的算法,而不需要修改现有代码。这就是策略模式的魅力所在!✨
记住,当你的代码中出现大量的if-else判断来选择不同算法时,考虑一下策略模式,它可能是你的最佳选择!💪
各位宝子们,策略模式的精髓就是这样啦!希望这篇文章能帮助你理解并应用这个实用的设计模式。如果有任何问题,欢迎在评论区留言讨论!下期见!👋
更多推荐

所有评论(0)