设计模式之策略模式
Posted liwangcai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式之策略模式相关的知识,希望对你有一定的参考价值。
1. 策略模式的作用
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。
2. 为什么要使用策略模式?
我们想象一下最常见的场景:排序。排序无非两种选择,升序或降序。如果我们要封装一个类要自由的切换两种排序要怎么做呢?
最常见的做法是这样的:
public class Demo { public void sort(boolean asc) { if (asc) { //判断是否要升序 //实现升序的算法 } else { //实现降序的算法 } } }
我们可以发现这要的代码极不美观,而且这还是只有两种情况的时候,加入有N中情况那岂不是要写很多的判断。甚至可能大多数时候我们并不能提前想好所有的类型,如果临时要加入新的算法只能再次修改原来的代码。维护很困难。这时候我们就可以使用策略模式来实现。
3. 怎么使用策略模式?
以上述排序为例,在java中我们需要实现自己的比较器。
public static void main(String[] args) { List<Integer> list = new ArrayList<>(); Collections.sort(list, new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o1 - o2; } }); }
如此,当我们在需要定义新的排序规则(因为排序的对象可能是多种多样的),当我们需要一个新的规则时,我们不需要去修改Collections.sort()方法的内容,而是实现一个自己的比较器,这样就可以实现新的排序。
4. 分析一下策略模式是怎么构成的?
我们同样以上述排序为例:
(1)策略接口
@FunctionalInterface public interface Comparator<T> { 这是策略接口
int compare(T o1, T o2); 这是实现不同策略的接口函数
(2)不同的实现
class MyComparator4Integer implements Comparator{ //为了比较Integer类型而实现的类 @Override public int compare(Object o1, Object o2) { return 0; } }
class MyComparator4String implements Comparator{ //为了比较String类型而实现的类
@Override
public int compare(Object o1, Object o2) {
return 0;
}
}
(3)调用者中(其中一个
private static <T> void binarySort(T[] a, int lo, int hi, int start, Comparator<? super T> c) { assert lo <= start && start <= hi; if (start == lo) start++; for ( ; start < hi; start++) { T pivot = a[start]; // Set left (and right) to the index where a[start] (pivot) belongs int left = lo; int right = start; assert left <= right; /* * Invariants: * pivot >= all in [lo, left). * pivot < all in [right, start). */ while (left < right) { int mid = (left + right) >>> 1; if (c.compare(pivot, a[mid]) < 0) //在调用者中会调用策略函数,当传入的比较器不同时,比较的规则也会随之改变 right = mid; else left = mid + 1; } assert left == right; /* * The invariants still hold: pivot >= all in [lo, left) and * pivot < all in [left, start), so pivot belongs at left. Note * that if there are elements equal to pivot, left points to the * first slot after them -- that‘s why this sort is stable. * Slide elements over to make room for pivot. */ int n = start - left; // The number of elements to move // Switch is just an optimization for arraycopy in default case switch (n) { case 2: a[left + 2] = a[left + 1]; case 1: a[left + 1] = a[left]; break; default: System.arraycopy(a, left, a, left + 1, n); } a[left] = pivot; } }
)
以上是关于设计模式之策略模式的主要内容,如果未能解决你的问题,请参考以下文章