-
策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。
-
策略模式的Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法中的公共功能。
-
策略模式的主要优点如下。
- 多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句,如 if…else 语句、–switch…case 语句。
- 策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。
- 策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。
- 策略模式提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。
- 策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。
-
其主要缺点如下。
- 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。
- 策略模式造成很多的策略类,增加维护难度。
- 简单实现利用策略模式随意替换各种排序算法
- Strategy接口
public interface AlgorithmStrategy {
void sortMethod(int[] nums);
}
- ConcrtetStrategy,封装了具体的算法或行为,实现了Strategy接口
public class MergeSort implements AlgorithmStrategy{
private int[] aux;
@Override
public void sortMethod(int[] nums) {
aux = new int[nums.length];
mergeSort(nums, 0, nums.length - 1);
System.out.println("归并排序完成!");
}
public void mergeSort(int[] nums, int low, int high){
if (low >= high)
return;
int middle = low + (high - low) / 2;
mergeSort(nums, low, middle);
mergeSort(nums, middle + 1, high);
merge(nums, low, middle, high);
}
public void merge(int[] nums, int low, int middle, int high){
int left = low;
int right = middle + 1;
for (int i = low; i <= high; i++)
aux[i] = nums[i];
for (int i = low; i <= high; i++){
if (left > middle)
nums[i] = aux[right++];
else if (right > high)
nums[i] = aux[left++];
else if (aux[left] > aux[right])
nums[i] = aux[right++];
else
nums[i] = aux[left++];
}
}
}
public class QuickSort implements AlgorithmStrategy{
@Override
public void sortMethod(int[] nums) {
quickSort(nums, 0, nums.length - 1);
System.out.println("快速排序完毕!");
}
public void quickSort(int[] nums, int low, int high){
if (low >= high)
return;
int left = low;
int right = high;
int pivot = nums[left];
while (left < right){
while (left < right){
if (nums[right] >= pivot)
right--;
else {
nums[left] = nums[right];
break;
}
}
while (left < right){
if (nums[left] <= pivot)
left++;
else {
nums[right] = nums[left];
break;
}
}
}
int pivotIndex = left;
nums[left] = pivot;
quickSort(nums, low, pivotIndex - 1);
quickSort(nums, pivotIndex + 1, high);
}
}
- Context类,维护一个对Strategy对象的引用
public class AlgorithmContext {
AlgorithmStrategy algorithmStrategy;
// public AlgorithmContext(AlgorithmStrategy algorithmStrategy){
// this.algorithmStrategy = algorithmStrategy;
// }
public AlgorithmContext(){
}
public AlgorithmContext(String methodName){
try {
Class<AlgorithmStrategy> algorithmStrategyClass = (Class<AlgorithmStrategy>) Class.forName(methodName);
algorithmStrategy = algorithmStrategyClass.getConstructor().newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
public void implementSort(int[] nums){
algorithmStrategy.sortMethod(nums);
}
}
- 客户端代码
public class StrategyPattern {
public int[] sortNums(int[] nums, String methodName){
AlgorithmContext algorithmContext = new AlgorithmContext(methodName);
algorithmContext.implementSort(nums);
return nums;
}
public static void main(String[] args) {
StrategyPattern strategyPattern = new StrategyPattern();
int[] nums = {5, 9, 1, -4, 5, 3, 7, 6, 1, 32, 23, 42, 57, 2, -49, 4, 67};
strategyPattern.sortNums(nums, "com.chong.strategy.QuickSort");
System.out.println(Arrays.toString(nums));
int[] nums2 = {5, 9, 1, -4, 5, 3, 7, 6, 1, 32, 23, 42, 57, 2, -49, 4, 67};
strategyPattern.sortNums(nums2, "com.chong.strategy.MergeSort");
System.out.println(Arrays.toString(nums2));
}
}
输出结果:
快速排序完毕!
[-49, -4, 1, 1, 2, 3, 4, 5, 5, 6, 7, 9, 23, 32, 42, 57, 67]
归并排序完成!
[-49, -4, 1, 1, 2, 3, 4, 5, 5, 6, 7, 9, 23, 32, 42, 57, 67]