抽丝剥茧 细说架构那些事——【优锐课】
策略设计模式是Java API库中常见的模式之一。这与另一个设计模式(称为状态设计模式)非常相似。本文是在学习完优锐课JAVA架构VIP课程—【框架源码专题】中《学习源码中的优秀设计模式》后写下的学习感悟。简要介绍了该思想,并提供了有关如何在Java中实现该思想的示例。
总览
策略模式也称为策略模式。它被归类为行为软件设计模式,其中重点是在对象之间找到灵活的通信模式。它有助于在运行时对象之间建立灵活的通信。
策略模式
策略模式的基本思想是在类的较小层次扩展中组合一组操作。与该策略相关的对象确定在给定情况下将使用哪种算法。例如,它使我们能够在运行时交换算法的实现细节,而无需我们重写它。这个想法与依赖注入中的实现模式产生了共鸣,因为它还允许在测试过程中将实现换出,例如在测试代码中执行模拟实现。
从状态设计模式的角度来看,它类似于状态设计模式,它是封装上下文对象状态的对象。策略设计模式中的对象类似地封装了算法的实现,并且可以根据需要在运行时交换事件。
在Java API库中,java.awt.Container组件是使用此模式的示例。此处,LayoutManager充当策略对象。这些类(例如BorderLayout,FlowLayout和GridLayout)实现接口LayoutManager。实现的类定义一个名为addLayoutComponent()的方法。此方法内的定义确定逻辑,或如何将组件布置在Container对象中。例如,FlowLayout从左到右放置它们,而BorderLayout将它们放置在名为CENTER,NORTH,EAST,SOUTH,WEST的区域中。 Container类包含称为LayoutManager对象的策略对象。因为该接口包含对实现该接口的类的对象的引用,所以策略对象可以随时引用已实现的类。
策略模式的使用
它基本上是从通用基类继承的类的集合。它具有相同的基本结构和通用功能,但区别在于使用方式。可以说,它按照所应用的策略起作用。策略模式通过提供运行时灵活性来增强你的能力。与其他类似的模式(例如状态和命令)不同,可以通过创建代理类来利用这种灵活性,该代理类在运行时控制特定策略的选择。
实现策略模式
这是此模式的快速实现。这个想法很简单,但是可以有效地选择所需的实现并根据需要进行交换。没什么好想的,类的接口和层次结构创建了演绎,这是在代码中使用的一种策略。
在这里,它使我们能够使用Sort接口编写代码,而我们想要排序的代码不必关心用于排序的算法。通过对接口和适合特定实现的类结构进行编程,我们可以根据需要使用接口,并在需要其他接口时立即更改策略。从某种意义上说,这个想法是可扩展的,在以后,我们可以添加更多的实现。针对该接口编写的任何代码都不会更改,但可以使用新的实现。
1 package org.mano.example; 2 public interface Sort { 3 int [] sort(int[] nos); 4 } 5 package org.mano.example; 6 public class BubbleSort implements Sort{ 7 @Override 8 public int [] sort(int[] nos) { 9 System.out.println("\n--- BUBBLE SORT strategy 10 in action---\n"); 11 int n = nos.length; 12 for (int i = 0; i < n-1; i++) 13 for (int j = 0; j < n-i-1; j++) 14 if (nos[j] > nos[j+1]) 15 { 16 int tmp = nos[j]; 17 nos[j] = nos[j+1]; 18 nos[j+1] = tmp; 19 } 20 return nos; 21 } 22 } 23 package org.mano.example; 24 public class SelectionSort implements Sort{ 25 @Override 26 public int [] sort(int [] nos) { 27 System.out.println("\n--- SELECTION SORT strategy 28 in action ---\n"); 29 int n = nos.length; 30 for (int i = 0; i < n-1; i++) 31 { 32 int mindex = i; 33 for (int j = i+1; j < n; j++) 34 if (nos[j] < nos[mindex]) 35 mindex = j; 36 int temp = nos[mindex]; 37 nos[mindex] = nos[i]; 38 nos[i] = temp; 39 } 40 return nos; 41 } 42 } 43 package org.mano.example; 44 public class ShellSort implements Sort { 45 @Override 46 public int [] sort(int[] nos) { 47 System.out.println("\n--- SHELL SORT strategy 48 in action ---\n"); 49 int n = nos.length; 50 for (int part = n/2; part > 0; part /= 2) 51 { 52 for (int i = part; i < n; i += 1) 53 { 54 int temp = nos[i]; 55 int j; 56 for (j = i; j >= part && nos[j - part] > 57 temp; j -= part) nos[j] = nos[j - part]; 58 nos[j] = temp; 59 } 60 } 61 return nos; 62 } 63 } 64 package org.mano.example; 65 import java.util.Random; 66 public class SortingApp { 67 private Sort sortStrategy; 68 public SortingApp(Sort sort){ 69 this.sortStrategy = sort; 70 } 71 public int [] sort(int[] data){ 72 return sortStrategy.sort(data); 73 } 74 public void changeStrategy(Sort anotherStrategy){ 75 sortStrategy = anotherStrategy; 76 } 77 public void printArray(int arr[]) 78 { 79 int n = arr.length; 80 for (int i=0; i<n; ++i) 81 System.out.print(arr[i]+" "); 82 System.out.println(); 83 } 84 public static int [] getDummyData(){ 85 Random r = new Random(); 86 int [] data = new int [10]; 87 for (int i=0;i<10;i++) 88 data[i] = r.nextInt(100); 89 return data; 90 } 91 public static void main(String[] args){ 92 SortingApp app = new SortingApp(new BubbleSort()); 93 app.printArray(app.sort(getDummyData())); 94 app.changeStrategy(new SelectionSort()); 95 app.printArray(app.sort(getDummyData())); 96 app.changeStrategy(new ShellSort()); 97 app.printArray(app.sort(getDummyData())); 98 } 99 }
输出
1 --- BUBBLE SORT strategy in action--- 2 3 5 15 22 38 41 45 56 72 72 97 4 5 --- SELECTION SORT strategy in action --- 6 7 42 47 52 55 60 76 79 82 86 96 8 9 --- SHELL SORT strategy in action --- 10 11 11 13 19 24 27 33 47 72 72 88
结论
策略模式使我们能够将有关要使用的实施策略的决策推迟到运行时为止。当我们使用Spring Framework将XML用作配置文件来构造对象及其依赖项时,将在运行时读取它。这种模式的主要优点是它利用了实现之间的动态变化,而无需重新编译。
感谢阅读!欢迎留言。想更深入探讨学习也欢迎私信我。下篇继续~