4

初识设计模式 - 策略模式 - 程序员翔仔

 1 year ago
source link: https://www.cnblogs.com/fatedeity/p/16805489.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

初识设计模式 - 策略模式

策略设计模式(Strategy Design Pattern)实际上起到一个解耦的作用,解耦了策略的定义、创建、使用三部分。

其概念是,定义一系列算法类,将每一个算法封装起来,并让它们可以互相替换。

从代码的层面上理解就是,将面向过程编程中的分支(如 if-else 或 switch 分支)代码,转换成面向对象的算法类,通过构建这些类的关系以实现不同分支的选择,实现运行时选择策略。

在这里,使用一个加、减、乘的案例来展示策略模式的应用。

首先,对加、减、乘运算抽象出一个公共的方法,定义一个 Strategy 策略接口,其代码示例如下:

public interface Strategy { // 加、减、乘、除都是对两个数进行处理 int doOperation(int num1, int num2);}

对于加法,实现 Strategy 策略接口,定义一个 OperationAdd 策略类,其代码示例如下:

public class OperationAdd implements Strategy { @Override public int doOperation(int num1, int num2) { return num1 + num2; }}

对于减法,实现 Strategy 策略接口,定义一个 OperationSubtract 策略类,其代码示例如下:

public class OperationSubtract implements Strategy { @Override public int doOperation(int num1, int num2) { return num1 - num2; }}

对于乘法,实现 Strategy 策略接口,定义一个 OperationMultiply 策略类,其代码示例如下:

public class OperationMultiply implements Strategy { @Override public int doOperation(int num1, int num2) { return num1 * num2; }}

通常,会定义一个 Context 类用于汇总策略类,以方便客户端使用,其代码示例如下:

public class Context { private final Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public int executeStrategy(int num1, int num2) { return strategy.doOperation(num1, num2); }}

对于客户端而言,需要理解 Context 类如何使用,以及知道所有的策略类,通过注入不同的 Strategy 对象以达到选择不同策略的效果。

如下是客户端使用策略模式的代码示例:

public class StrategyDemo { public static void main(String[] args) { Context context = new Context(new OperationAdd()); // 10 + 5 = 15 System.out.println("10 + 5 = " + context.executeStrategy(10, 5)); context = new Context(new OperationSubtract()); // 10 - 5 = 5 System.out.println("10 - 5 = " + context.executeStrategy(10, 5)); context = new Context(new OperationMultiply()); // 10 * 5 = 50 System.out.println("10 * 5 = " + context.executeStrategy(10, 5)); }}

策略模式的主要优点如下:

  • 使用策略模式可以避免使用多重条件语句,如 if-else 或 switch 语句
  • 策略模式提供了管理相关算法族的办法,如恰当地使用继承把算法族的公共代码转移到父类中
  • 策略模式提供了相同行为的不同实现,客户端可以根据不同的需求使用不同的策略
  • 可以在不更改原代码的模式下,灵活增加新的算法,符合开闭原则
  • 策略模式把算法的使用放到环境类中,把实现放到具体策略类中,把定义放到客户端中,实现了三者的解耦

策略模式的主要缺点如下:

  • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类
  • 策略模式造成很多策略类,增加了维护难度

策略模式的适用场景如下:

  • 一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中
  • 对于多重条件语句,使用策略模式将这些行为转移到相应的具体策略类中,以替代这些条件语句
  • 系统要求使用算法的客户端不应该知道其操作的数据时,可以使用策略模式来封装算法及其数据结构

在 JDK 中,Comparator 接口就是一个策略模式的应用。

实际使用时,Comparator 就是策略接口,使用匿名内部类来实现具体策略类。如下是使用的示例代码:

import java.util.Arrays;import java.util.Comparator; public class ComparatorDemo { public static void main(String[] args) { String[] names = {"张三", "李四", "小明"}; Comparator<String> comparator = new Comparator<>() { @Override public int compare(String o1, String o2) { return o1.compareTo(o2); } }; Arrays.sort(names, comparator); // [小明, 张三, 李四] System.out.println(Arrays.toString(names)); }}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK