美文网首页
设计模式 - 策略模式

设计模式 - 策略模式

作者: FX_SKY | 来源:发表于2017-04-26 23:15 被阅读15次

模式定义

定义一系列算法,将它们一个个封装起来,并且使他们之间可以相互替换。本模式使得算法可以独立于使用它的客户而变化。

策略模式是对算法的封装,把一系列的算法分别封装到对应的类中,并且这些类实现相同的接口,相互之间可以替换。在前面说过的行为类模式中,有一种模式也是关注对算法的封装——模版方法模式,对照类图可以看到,策略模式与模版方法模式的区别仅仅是多了一个单独的封装类Context,它与模版方法模式的区别在于:在模版方法模式中,调用算法的主体在抽象的父类中,而在策略模式中,调用算法的主体则是封装到了封装类Context中,抽象策略Strategy一般是一个接口,目的只是为了定义规范,里面一般不包含逻辑。

模式结构

Strategy.jpg
  • 环境类(Context):也叫上下文,对策略进行二次封装,目的是避免高层模块对策略的直接调用。
  • 抽象策略(Strategy):通常情况下为一个接口,当各个实现类中存在着重复的逻辑时,则使用抽象类来封装这部分公共的代码,此时,策略模式看上去更像是模版方法模式。
  • 具体策略(ConcreteStrategy):具体策略角色通常由一组封装了算法的类来担任,这些类之间可以根据需要自由替换。

代码实现

public class Context {
    private Strategy strategy;

    public void setStrategy(Strategy strategy){
        this.strategy = strategy;
    }

    public void algorithm(){
        strategy.algorithm();
    }
}

抽象策略类Strategy :

public interface Strategy {
    void algorithm();
}

具体策略实现:

public class ConcreteStrategyA implements Strategy {

    @Override
    public void algorithm() {
        System.out.println("具体策略1");
    }
}

public class ConcreteStrategyB implements Strategy {

    @Override
    public void algorithm() {
        System.out.println("具体策略2");
    }
}

Client:

        Context context = new Context();
        System.out.println("-----执行策略1-----");
        context.setStrategy(new ConcreteStrategyA());
        context.algorithm();

        System.out.println("-----执行策略2-----");
        context.setStrategy(new ConcreteStrategyA());
        context.algorithm();

排序算法

排序策略接口:

public interface Sort {

    void sort(int[] arr, int start, int end);
}

冒泡排序:

public class BubbleSort implements Sort {

    @Override
    public void sort(int[] arr, int start, int end) {
        System.out.println("冒泡排序实现");
        for(int i=start; i<end; i++){
            for(int j = start; j<arr.length-i-1; j++){
                //这里-i主要是每遍历一次都把最大的i个数沉到最底下去了,没有必要再替换了
                if(arr[j]>arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
    }
}

快速排序:

public class QuickSort implements Sort {

    @Override
    public void sort(int[] arr, int start, int end) {
        System.out.println("快速排序实现");
        quickSort(arr, start, end-1);
    }

    private void quickSort(int[] numbers, int start, int end) {
        if (start < end) {
            int base = numbers[start]; // 选定的基准值(第一个数值作为基准值)
            int temp; // 记录临时中间值
            int i = start, j = end;
            do {
                while ((numbers[i] < base) && (i < end))
                    i++;
                while ((numbers[j] > base) && (j > start))
                    j--;
                if (i <= j) {
                    temp = numbers[i];
                    numbers[i] = numbers[j];
                    numbers[j] = temp;
                    i++;
                    j--;
                }
            } while (i <= j);
            if (start < j)
                quickSort(numbers, start, j);
            if (end > i)
                quickSort(numbers, i, end);
        }
    }
}

上下文环境:

public class Context {
    private Sort strategy;

    public void setStrategy(Sort strategy){
        this.strategy = strategy;
    }

    public void sort(int[] arr, int start, int end) {
        strategy.sort(arr, start, end);
    }
}

客户端:

public class SortClient {

    public static void main(String[] args) {

        int[] arr = {10, 1, 8, 6, 5, 3, 2};

        Context context = new Context();
        System.out.println("-----执行冒泡排序-----");
        context.setStrategy(new BubbleSort());
        context.sort(arr, 0, arr.length);

        System.out.println("-----执行快速排序-----");
        context.setStrategy(new QuickSort());
        context.sort(arr, 0, arr.length);
    }
}

优缺点

优点

策略模式的优点:

  • 策略模式提供了对“开闭原则”的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。
  • 策略模式提供了可以替换继承关系的办法。
  • 使用策略模式可以避免使用多重条件转移语句。

缺点

  • 客户必须了解不同的Strategy
  • 策略模式将造成产生很多策略类

源码下载

https://github.com/TiFG/design-patterns/tree/master/strategy

相关文章

网友评论

      本文标题:设计模式 - 策略模式

      本文链接:https://www.haomeiwen.com/subject/ghowzttx.html