策略模式简介:
我们在开发的时候经常会遇到一些相关的问题,比如对于算法的选择,我们需要根据不同情况选择不同的算法,拿排序算法举例,我们可以使用堆排序,选择排序,快速排序,希尔排序等等不同的算法。
针对上述所说,我们常规会把算法全部分装在一个类中,想使用哪个,就可以方便的调用哪个方法。但是,当多个算法集中在一个类中的时候,会使得类变的臃肿,不容易维护,这时候我们的策略模式的孕育而出了。
策略模式定义
将策略抽象出来,提供一个统一的接口,不同的算法或者策略有不同的实现类,这样在客户端我们可以通过注入不同的对象实现算法或者策略的动态替换,称为策略类。
策略模式UML图:
下面就一排序算法啊为例,进行策略模式的介绍:
首先我们按照常规方法来写一个总类进行排序算法的收集,代码类如下:
public class SufaManager {
//希尔排序
public void shellSort( int[] a )
{
}
//快速排序
public void quickSort(int[] a,int begin,int end)
{
}
//冒泡排序
public void puppleSort(int[] a){
}
}
我们使用三个算法进行类的初始化,当我们需要使用不同的算法的时候,我们可以通过调用不同方法实现算法,但是我们也知道,这样的耦合性太大了,且不符合单一职责原则,所以我们进行解耦操作:
我们首先定义一个接口类:
//实现选择算法
public interface SortImp {
void chooseSort(int[] a);
}
然后我们将三个算法进行解耦分离,使得SufaManager只需要进行进行算法选择的职责,满足单一职责原则:
//希尔排序
public class ShellSort implements SortImp{
@Override
public void chooseSort(int[] a) {
int group= a. length/2;
int j;
for(; group>=1; group/=2)
{
for( int i= group; i< a. length; i++)
{
int temp= a[ i];
for( j= i- group; j>=0&& a[ j]> temp; j-= group)
{
a[ j+ group]= a[ j];
}
a[ j+ group]= temp;
}
}
}
}
//快排
public class QuickSort implements SortImp{
@Override
public void chooseSort(int[] a) {
sortDemo(a, 0, a.length-1);
}
public void sortDemo(int[] a,int begin,int end){
if (begin<end)
{
int i=find(a, begin, end);
sortDemo(a, begin, i-1);
sortDemo(a, i+1, end);
}
}
//进行基点的确定
public int find(int[] a,int begin,int end)
{
int x=a[begin];
int j=end;
int i=begin;
boolean flag=true;
while (i!=j)
{
if (flag)
{
//从右向左找到比x小的元素,进行填坑操作,一定要从右边先开始!
for(;j>i;j--)
{
if (a[j]<x)
{
//填坑
a[i++]=a[j];
//只找一个数,break;跳出
flag=false;
break;
}
}
}else
{
//从左向右找到比x大的元素,进行填坑操作
for(;i<j;i++)
{
if (a[i]>x)
{
//填坑
a[j--]=a[i];
flag=true;
break;
}
}
}
}
a[i]=x;
return i;
}
}
//冒泡
public class PuppleSort implements SortImp{
@Override
public void chooseSort(int[] a) {
//这里写下冒泡算法
for(int i=0;i<a.length;i++)
{
for (int j = 0; j < a.length; j++)
{
int temp;
if (a[j]<a[i])
{
temp=a[j];
a[j]=a[i];
a[i]=temp;
}
}
}
}
}
我们分类完成,接着写我们的manager类就好了:
public class SufaManager {
SortImp sortImp=null;
public void setSortImp(SortImp sortImp){
this.sortImp=sortImp;
}
public void getResult(int[]a){
sortImp.chooseSort(a);
}
}
测试类及结果:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] a=new int[]{2,3,4,1,7,23,12,56,98,76,45,32,21,35,46,78,45,11};
int[] b=new int[]{2,3,4,1,7,23,12,56,98,76,45,32,21,35,46,78,45,11};
int[] c=new int[]{2,3,4,1,7,23,12,56,98,76,45,32,21,35,46,78,45,11};
SufaManager sufaManager=new SufaManager();
sufaManager.setSortImp(new PuppleSort());
sufaManager.getResult(a);
System.out.println("冒泡排序:");
System.out.println(Arrays.toString(a));
sufaManager.setSortImp(new QuickSort());
System.out.println("快速排序");
sufaManager.getResult(b);
System.out.println(Arrays.toString(b));
sufaManager.setSortImp(new ShellSort());
System.out.println("希尔排序");
sufaManager.getResult(c);
System.out.println(Arrays.toString(c));
}
}
冒泡排序:
[98, 78, 76, 56, 46, 45, 45, 35, 32, 23, 21, 12, 11, 7, 4, 3, 2, 1]
快速排序
[1, 2, 3, 4, 7, 11, 12, 21, 23, 32, 35, 45, 45, 46, 56, 76, 78, 98]
希尔排序
[1, 2, 3, 4, 7, 11, 12, 21, 23, 32, 35, 45, 45, 46, 56, 76, 78, 98]
这样策略类就算完成啦~