设计模式-行为型之策略模式

模式动机

   在软件系统中,实现某一个功能时可能会有多种算法,比如排序功能就可以有冒泡排序,插入排序,选择排序等等多种实现方式,一种常用的方法是可以将这些算法写到一个类中,在该类中提供多个方法,每一个方法对应一个具体的查找算法。这种实现方式我们称之为硬编码,如果需要增加一种新的查找算法,需要修改封装算法类的源代码;更换查找算法,也需要修改客户端调用代码。同时,这个算法类中封装了大量排序算法,代码将较复杂,维护较困难。为了解决这些问题,可以定义一些独立的类来封装不同的算法,每一个类封装一个具体的算法,每一个封装算法的类我们都可以称之为策略,为了保证这些策略的一致性,一般会用一个抽象的策略类来做算法的定义,而具体每种算法则对应于一个具体策略类。

模式定义

  定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化。

模式结构

设计模式-行为型之策略模式_第1张图片
  环境类:Context,维护一个Strategy对象,让Strategy可以访问它的数据
  抽象策略类:Strategy,定义所有支持的算法的公共接口
  具体策略类:ConcreteStrategy,某个具体的算法

代码示例

  我们以排序算法为例,常见的排序算法如冒泡排序,选择排序,插入排序等等。每个排序我们封装成一个策略类。

//排序环境类
public class SortContext{
    private SortStrategy sort;
    public void setSort(SortStrategy sort){
        this.sort = sort;
    }
    public int[] sort(int[] arr){
        return sort.sort(arr);
    }
}
//排序策略类
public interface SortStrategy {
    public int[] sort(int[] arr);
}
//具体策略类-冒泡排序
public class BubbleSort implements SortStrategy{
    @Override
    public int[] sort(int[] arr) {
        int temp = 0;
        for(int i=0;i1;i++){
            for(int j=0;j1-i;j++){
                if(arr[j]>arr[j+1]){
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
        return arr;
    }
}
//具体策略类-选择排序
public class SelectSort implements SortStrategy{
    @Override
    public int[] sort(int[] arr) {
        int temp = 0;
        for(int i=0;i1;i++){
            for(int j=i+1;jif(arr[i]>arr[j]){
                    temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
        return arr;
    }
}
//客户端
public class Client {
    public static void main(String[] args) {
        int arr[] = {3,5,2,1,4,0,8,7,9,6};
        SortContext content = new SortContext();
        SortStrategy bubble = new BubbleSort();
        content.setSort(bubble);
        printSortResult(content.sort(arr));

        SortStrategy select = new SelectSort();
        content.setSort(select);
        printSortResult(content.sort(arr));
    }
    public static void printSortResult(int[] arr){
        for(int i=0;iout.print(arr[i]);
        }
    }
}

策略模式与状态模式

  策略模式跟状态模式从类图结构上看具有惊人的相似性,很容易产生混淆。我们必须搞清楚两者的区别。
  1、在状态模式中,状态转换是由Context环境类或者是由具体的状态类来管理控制,而在策略模式中,具体使用哪种策略是由客户端决定;
  2、 在状态模式中,如果状态转换是由具体状态类进行管理,那么状态类则需要持有Context环境类的一个引用,而在策略模式中,策略类不需要持有Context环境类引用;
  3、在状态模式中,客户端无需关心具体的状态,状态会根据用户的操作自动切换,而策略模式中客户端需要知道所选的策略究竟是哪一个;
  所以,如果系统中某个类的对象存在多种状态,不同状态下行为有差异,而且这些状态之间可以发生转换时使用状态模式;如果系统中某个类的某一行为存在多种实现方式,而且这些实现方式可以互换时使用策略模式。

你可能感兴趣的:(设计模式)