策略模式的定义

策略模式是一种对象行为型模式,指的是对于对象的一种行为而言,在不同的场景下有不同的实现算法。譬如现在要对一个数组进行排序,排序方法有很多种(快速排序、冒泡排序等),在数据量多的时候我想使用快速排序,而在数据量少的时候我想使用冒泡排序,并且以后可能会增加其他的排序算法,这个时候应该如何组织代码才能符合设计模式的基本原则呢?

排序问题普通实现

对于上述排序问题,没有设计模式概念的人可能会写出以下代码:

public class Client{
    
    public void sort(int type,int [] arr){
        if(type == 1){
            bubbleSort(arr);
        }else if(type == 2){
            quickSort(arr);
        }
    }
    
    //冒泡排序
    public void bubbleSort(int [] arr){
        
    }
    
    //快速排序
    public void quickSort(int [] arr){
        
    }
    
    public static void main(String [] args){
        int [] arr = {5,2,3,6,1,8};
        Client client = new Client();
        //冒泡排序
        client.sort(1,arr);
        //快速排序
        client.sort(2,arr)
    }
}

这种方式固然能解决问题,并且只用一个类就实现了,但是后期如果想增加排序方式就得频繁地打开Client.java文件去修改代码,这就违背了开闭原则。那么如何在保证遵守开闭原则的同时可以解决这个问题呢,答案就是使用策略模式,使用策略模式解决这个问题的伪代码如下。

排序问题策略模式实现

首先定义一个ISortStrategy接口

public interface ISortStrategy{
    
    void sort(int [] arr);
    
}

再定义BubbleSortStrategy类实现ISortStrategy接口用于处理冒泡排序,定义QuickSortStrategy类实现ISortStrategy接口用于处理快速排序。

public class BubbleSortStrategy implements ISortStrategy{
    
    @Override
    public void sort(int [] arr){
        //冒泡排序代码
    }
    
}
public class QuickSortStrategy implements ISortStrategy{
    
    @Override
    public void sort(int [] arr){
        //快速排序代码
    }
    
}

然后定义SortTool类封装排序方法

public class SortTool{
    
    private ISortStrategy sortStrategy;
    
    public SortTool(ISortStrategy sortStrategy){ 
        this.sortStrategy = sortStrategy;
    }
    
    public void setSortStrategy(ISortStrategy sortStrategy){
        this.sortStrategy = sortStrategy;
    }
    
    public void sort(int [] arr){
        if(sortStrategy!=null){
            sortStrategy.sort(arr);
        }
    }
    
}

最后定义Client类执行调用

public class Client{
    
    public static void main(String [] args){
        int [] arr = {5,2,3,6,1,8};
        ISortStrategy bubbleSortStrategy = new BubbleSortStrategy();
        ISortStrategy quickSortStrategy = new QuickSortStrategy();
        SortTool sortTool = new SortTool(bubbleSortStrategy);
        sortTool.sort(arr);//冒泡排序
        sortTool.setSortStrategy(quickSortStrategy);//切换为快速排序
        sortTool.sort(arr);//快速排序
    }
    
}

当需要新增一种排序方式(譬如选择排序)时只需要新增SelectionSortStrategy类实现ISortStrategy接口并重写sort()方法就行,可以看出经过这样处理后我们的代码是完全遵守开闭原则的,要新增排序方式时只需要新增类实现ISortStrategy接口并重写sort()方法,然后在Client里初始化并使用即可,完全做到了对修改关闭、对扩展开放。策略模式的类图可以查看Graphic Design Pattern策略模式里绘制的。

策略模式的优缺点

优点

  1. 策略模式完全遵守”开闭原则”,用户可以在不修改原系统的基础上灵活选择算法和行为,同时也可以灵活添加算法和行为
  2. 策略模式可以避免多重条件语句的出现

缺点

  1. Client必须理解策略模式中所有算法或行为的作用才能决定使用哪种策略
  2. 策略模式会增加类的数量

相关文章:

策略模式

维基百科策略模式

设计模式六大原则(6):开闭原则

Graphic Design Pattern策略模式