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

本文介绍了策略模式的概念、动机及实现方式,通过排序算法的例子详细展示了如何使用策略模式将算法封装成独立的类,使得算法可以相互替换,提高了代码的灵活性。

模式动机

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

模式定义

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

模式结构

模式结构
  环境类: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;i<arr.length-1;i++){
            for(int j=0;j<arr.length-1-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;i<arr.length-1;i++){
            for(int j=i+1;j<arr.length;j++){
                if(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;i<arr.length;i++){
            System.out.print(arr[i]);
        }
    }
}

策略模式与状态模式

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值