一、策略模式
策略模式(Strategy Pattern)是一种行为设计模式,它允许你定义一系列算法,把每个算法封装起来,并让它们可以互相替换。这种模式使得算法可以在不影响客户端的情况下发生变化。
在策略模式中,有三个主要的角色:
- 策略接口(Strategy):通常是一个接口,定义了一个算法家族的所有算法的通用接口。
- 具体策略(ConcreteStrategy):实现了策略接口,包含具体的算法实现。
- 上下文(Context):持有一个策略对象的引用,并且可以在运行时动态地设置或更改策略。
示例代码
假设我们有一个系统需要对数据进行不同的排序方法,我们可以使用策略模式来实现:
1 // 1. 定义策略接口 2 public interface SortStrategy { 3 void sort(int[] numbers); 4 } 5 6 // 2. 具体策略:实现不同的排序算法 7 public class BubbleSortStrategy implements SortStrategy { 8 @Override 9 public void sort(int[] numbers) { 10 System.out.println("Using Bubble Sort"); 11 // 冒泡排序实现 12 int n = numbers.length; 13 for (int i = 0; i < n-1; i++) { 14 for (int j = 0; j < n-i-1; j++) { 15 if (numbers[j] > numbers[j+1]) { 16 // swap arr[j] and arr[j+1] 17 int temp = numbers[j]; 18 numbers[j] = numbers[j+1]; 19 numbers[j+1] = temp; 20 } 21 } 22 } 23 } 24 } 25 26 public class QuickSortStrategy implements SortStrategy { 27 @Override 28 public void sort(int[] numbers) { 29 System.out.println("Using Quick Sort"); 30 // 快速排序实现 31 quickSort(numbers, 0, numbers.length - 1); 32 } 33 34 private void quickSort(int[] arr, int low, int high) { 35 if (low < high) { 36 int pi = partition(arr, low, high); 37 quickSort(arr, low, pi-1); 38 quickSort(arr, pi+1, high); 39 } 40 } 41 42 private int partition(int[] arr, int low, int high) { 43 int pivot = arr[high]; 44 int i = (low-1); 45 for (int j = low; j < high; j++) { 46 if (arr[j] <= pivot) { 47 i++; 48 int temp = arr[i]; 49 arr[i] = arr[j]; 50 arr[j] = temp; 51 } 52 } 53 int temp = arr[i+1]; 54 arr[i+1] = arr[high]; 55 arr[high] = temp; 56 57 return i+1; 58 } 59 } 60 61 // 3. 上下文类 62 public class SortContext { 63 private SortStrategy strategy; 64 65 // 设置策略 66 public void setSortStrategy(SortStrategy strategy) { 67 this.strategy = strategy; 68 } 69 70 // 执行策略 71 public void executeStrategy(int[] numbers) { 72 strategy.sort(numbers); 73 } 74 } 75 76 // 4. 客户端代码 77 public class StrategyPatternDemo { 78 public static void main(String[] args) { 79 SortContext context = new SortContext(); 80 81 int[] numbers = {5, 2, 9, 1, 5, 6}; 82 83 // 使用冒泡排序 84 context.setSortStrategy(new BubbleSortStrategy()); 85 context.executeStrategy(numbers); 86 87 // 使用快速排序 88 context.setSortStrategy(new QuickSortStrategy()); 89 context.executeStrategy(numbers); 90 } 91 }
策略模式的优点是可以很方便的解耦,适用于有多种不同逻辑和算法的 if 场景,但不适用于大量的 if else 场景。
你可以创建一个Map<String, Runnable>
来实现不同的策略,Runnable
接口的run()
方法可以用来执行具体的策略。在这种设计中,每个策略都封装在一个实现Runnable
接口的类中,或者你可以使用匿名内部类或lambda表达式来直接定义策略。
-
策略映射:使用
Map<String, Runnable>
来存储策略,String
作为键来标识策略名称,Runnable
作为值来表示具体策略的执行逻辑。 -
策略定义:通过
lambda表达式
为每个策略定义Runnable
的run
方法。你也可以使用具体的类来实现这些策略。 -
策略执行:通过键值对的形式,从
Map
中获取指定的策略,然后使用Thread
启动策略的执行。
扩展
- 如果策略执行需要更多的上下文数据,你可以创建实现
Runnable
接口的具体类,并在其构造函数中传递所需的数据。 - 你还可以结合
Callable
接口来实现带返回值的策略模式。
以下是一个示例:
示例代码
import java.util.HashMap; import java.util.Map; public class StrategyPatternWithMap { public static void main(String[] args) { // 创建一个Map,key为策略名称,value为具体策略的Runnable实现 Map<String, Runnable> strategyMap = new HashMap<>(); // 添加策略到Map中 strategyMap.put("strategy1", () -> { System.out.println("Executing Strategy 1"); // 具体策略1的执行逻辑 }); strategyMap.put("strategy2", () -> { System.out.println("Executing Strategy 2"); // 具体策略2的执行逻辑 }); strategyMap.put("strategy3", () -> { System.out.println("Executing Strategy 3"); // 具体策略3的执行逻辑 }); // 获取并执行某个策略 String strategyKey = "strategy2"; // 假设我们需要执行策略2 Runnable strategy = strategyMap.get(strategyKey); if (strategy != null) { new Thread(strategy).start(); // 在新线程中执行策略 } else { System.out.println("Strategy not found: " + strategyKey); } } }
规则引擎
在软件开发中,使用规则引擎可以有效优化复杂的 if/else
逻辑,提高代码的可维护性、可扩展性和灵活性。规则引擎允许你将业务逻辑和决策规则从代码中分离出来,使得这些规则可以动态地进行配置和管理。
规则引擎的基本概念
规则引擎是一个用于管理和执行业务规则的系统。业务规则通常表示为条件和行动的集合,可以根据实际需要动态变化。规则引擎通过提供一种机制来定义、执行和维护这些规则,使得业务逻辑更加灵活和易于管理。
优化 if/else
逻辑的步骤
-
识别规则:将复杂的
if/else
逻辑分析成一系列独立的规则。每个规则通常由一个条件和一个对应的行动组成。 -
选择规则引擎:根据你的需求选择合适的规则引擎。常见的规则引擎包括:
- Drools:一个开源的业务规则管理系统(BRMS),支持复杂的规则定义和推理。
- Easy Rules:一个轻量级的 Java 规则引擎,适用于简单的规则定义。
- Jess:一个基于 Java 的规则引擎,支持强大的规则定义和执行。
-
定义规则:将识别出的规则转换为规则引擎支持的格式。这可能涉及到编写规则文件、定义规则类或配置规则。
-
集成规则引擎:将规则引擎集成到你的应用程序中。通常需要编写代码来加载规则、执行规则和处理规则引擎的输出。
-
测试和优化:测试规则引擎的配置和规则的执行,确保其按预期工作,并根据需要进行优化。
示例:使用 Drools 优化 if/else
假设我们有一个复杂的 if/else
逻辑,用于计算一个客户的折扣:
public class DiscountCalculator { public double calculateDiscount(Customer customer) { double discount = 0.0; if (customer.getAge() < 18) { discount = 0.10; // 10% 折扣 } else if (customer.getAge() >= 18 && customer.getAge() <= 25) { if (customer.isStudent()) { discount = 0.15; // 15% 学生折扣 } else { discount = 0.05; // 5% 青年折扣 } } else if (customer.getAge() > 25 && customer.getYearsAsCustomer() > 5) { discount = 0.20; // 20% 忠诚客户折扣 } else { discount = 0.05; // 5% 默认折扣 } return discount; } }
使用 Drools 优化
1. 添加 Drools 依赖
首先,在项目中添加 Drools 的依赖
<!-- Maven 依赖 --> <dependency> <groupId>org.drools</groupId> <artifactId>drools-core</artifactId> <version>8.26.2.Final</version> </dependency>
2.定义规则文件
创建一个.drl文件来定义规则,例如discounts.drl
package com.example.rules; import com.example.Customer; rule "Minor Discount" when $c : Customer(age < 18) then $c.setDiscount(0.10); end rule "Student Discount" when $c : Customer(age >= 18 && age <= 25, isStudent == true) then $c.setDiscount(0.15); end rule "Youth Discount" when $c : Customer(age >= 18 && age <= 25, isStudent == false) then $c.setDiscount(0.05); end rule "Loyal Customer Discount" when $c : Customer(age > 25, yearsAsCustomer > 5) then $c.setDiscount(0.20); end rule "Default Discount" when $c : Customer() then $c.setDiscount(0.05); end
3.集成drools
在代码中加载并执行
import org.drools.compiler.compiler.DroolsParserException; import org.kie.api.KieServices; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; public class DiscountCalculator { private KieSession kSession; public DiscountCalculator() { KieServices ks = KieServices.Factory.get(); KieContainer kContainer = ks.getKieClasspathContainer(); kSession = kContainer.newKieSession("ksession-rules"); } public double calculateDiscount(Customer customer) { kSession.insert(customer); kSession.fireAllRules(); return customer.getDiscount(); } }
通过使用规则引擎,你可以将复杂的 if/else
逻辑提取到外部规则文件中,使得业务逻辑更加清晰、灵活和易于管理。这种方式不仅提高了代码的可维护性,还使得业务规则能够更方便地进行修改和扩展。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具