策略设计模式是Java API库中常见的模式之一。这与另外一个设计模式(称为状态设计模式)很是类似。本文是在学习完优锐课JAVA架构VIP课程—【框架源码专题】中《学习源码中的优秀设计模式》后写下的学习感悟。简要介绍了该思想,并提供了有关如何在Java中实现该思想的示例。html
策略模式也称为策略模式。它被归类为行为软件设计模式,其中重点是在对象之间找到灵活的通讯模式。它有助于在运行时对象之间创建灵活的通讯。算法
策略模式的基本思想是在类的较小层次扩展中组合一组操做。与该策略相关的对象肯定在给定状况下将使用哪一种算法。例如,它使咱们可以在运行时交换算法的实现细节,而无需咱们重写它。这个想法与依赖注入中的实现模式产生了共鸣,由于它还容许在测试过程当中将实现换出,例如在测试代码中执行模拟实现。编程
从状态设计模式的角度来看,它相似于状态设计模式,它是封装上下文对象状态的对象。策略设计模式中的对象相似地封装了算法的实现,而且能够根据须要在运行时交换事件。设计模式
在Java API库中,java.awt.Container组件是使用此模式的示例。此处,LayoutManager充当策略对象。这些类(例如BorderLayout,FlowLayout和GridLayout)实现接口LayoutManager。实现的类定义一个名为addLayoutComponent()的方法。此方法内的定义肯定逻辑,或如何将组件布置在Container对象中。例如,FlowLayout从左到右放置它们,而BorderLayout将它们放置在名为CENTER,NORTH,EAST,SOUTH,WEST的区域中。 Container类包含称为LayoutManager对象的策略对象。由于该接口包含对实现该接口的类的对象的引用,因此策略对象能够随时引用已实现的类。架构
它基本上是从通用基类继承的类的集合。它具备相同的基本结构和通用功能,但区别在于使用方式。能够说,它按照所应用的策略起做用。策略模式经过提供运行时灵活性来加强你的能力。与其余相似的模式(例如状态和命令)不一样,能够经过建立代理类来利用这种灵活性,该代理类在运行时控制特定策略的选择。app
这是此模式的快速实现。这个想法很简单,可是能够有效地选择所需的实现并根据须要进行交换。没什么好想的,类的接口和层次结构建立了演绎,这是在代码中使用的一种策略。框架
在这里,它使咱们可以使用Sort接口编写代码,而咱们想要排序的代码没必要关心用于排序的算法。经过对接口和适合特定实现的类结构进行编程,咱们能够根据须要使用接口,并在须要其余接口时当即更改策略。从某种意义上说,这个想法是可扩展的,在之后,咱们能够添加更多的实现。针对该接口编写的任何代码都不会更改,但可使用新的实现。dom
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用做配置文件来构造对象及其依赖项时,将在运行时读取它。这种模式的主要优势是它利用了实现之间的动态变化,而无需从新编译。ide
感谢阅读!欢迎留言。想更深刻探讨学习也欢迎私信我。下篇继续~