设计模式-Strategy策略模式详解

简介: 设计模式-Strategy策略模式详解

策略模式是什么?


策略模式定义一系列算法,封装每个算法,并使他们可以互换,不同的策略可以让算法独立于使用它们的客户而变化。 以上定义来自设计模式之美



是不是很抽象,下面我们就用模拟Comparator接口为大家讲解策略模式,首先我定义一个Cat类,里面有weight,height,age 属性

public class Cat {
    int weight, height,age;
    public Cat(int weight, int height,int age) {
        this.weight = weight;
        this.height = height;
        this.age = age;
    }
    @Override
    public int compareTo(Cat c) {
        if(this.weight < c.weight) {
            return -1;
        } else if(this.weight > c.weight) {
            return 1;
        } else {
            return 0;
        }
    }
    @Override
    public String toString() {
        return "Cat{" +
            "weight=" + weight +
            ", height=" + height +
            ", age=" + age +
            '}';
    }
}
复制代码



现在我们要实现Cat类数组的排序,按weight属性升序,我们定义一个Sorter类,Cat类中定义compareTo方法,方法是按Cat类中的weight属性比较,我们通过选择排序实现Cat数组的排序

public class Sorter {
    public void sort(Cat[] arr) {
        //选择排序
        for(int i=0; i<arr.length - 1; i++) {
            int minPos = i;
            for(int j=i+1; j<arr.length; j++) {
                minPos = arr[j].compareTo(arr[minPos])==-1 ? j : minPos;
            }
            swap(arr, i, minPos);
        }
    }
    void swap(Cat[] arr, int i, int j) {
        Cat temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
     public static void main(String[] args) {
        Cat[] a = {new Cat(3, 3), new Cat(5, 5), new Cat(1, 1)};
        Sorter sorter = new Sorter();
        sorter.sort(a);
        System.out.println(Arrays.toString(a));
    }
}
复制代码



假如现在我们要实现Cat类heigt属性或age属性排序,我们是不是每次都要修改compareTo方法,在设计模式中,有个对修改关闭,对扩展开放的开闭原则,我们每次都去修改compareTo方法违背了设计模式的思想,我们怎么进行扩展,我们定义Comparator接口,我们要实现那个属性的排序,就定义哪个属性的比较器

public interface Comparator<T> {
    int compare(T o1, T o2);
}
复制代码



height升序属性的比较器

public class CatHeightComparator implements Comparator<Cat> {
    @Override
    public int compare(Cat o1, Cat o2) {
        if(o1.height > o2.height) {
            return 1;
        } else if (o1.height < o2.height) {
            return -1;
        } else {
            return 0;
        }
    }
}
复制代码


public void sort(T[] arr, Comparator<T> comparator) {
    for(int i=0; i<arr.length - 1; i++) {
        int minPos = i;
        for(int j=i+1; j<arr.length; j++) {
            minPos = comparator.compare(arr[j],arr[minPos])==-1 ? j : minPos;
        }
        swap(arr, i, minPos);
    }
}
void swap(T[] arr, int i, int j) {
    T temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}
public static void main(String[] args) {
    Cat[] a = {new Cat(3, 3, 3), new Cat(5, 5, 5), new Cat(1, 1, 1)};
    Sorter<Cat> sorter = new Sorter<>();
    sorter.sort(a,new CatHeightComparator());
    System.out.println(Arrays.toString(a));
}
复制代码



以此类推,我们要实现age属性的排序,我义Cat类age的比较器,要实现weight属性的排序,就实现Cat类weight比较器,以上就是Comparator接口实现策略模式的过程,我们可以提前的把这些比较器定义成枚举类,在程序初始化的时候将每个比较器放入常量map当中,想要那种比较器就从map中取,避免if...else...判断,增加一个策略,就在初始化了添加一个

public enum ComparatorEnum {
    AGE("age","age排序"),
    WEIGHT("weight","weight排序"),
    HEIGHT("height","height排序");
    private String code;
    private String desc;
    ComparatorEnum(String code, String desc) {
        this.code = code;
        this.desc = desc;
    }
    public String getCode() {
        return code;
    }
    public String getDesc() {
        return desc;
    }
}
复制代码


private static final Map<String, Comparator> comparatorMap= new HashMap<>(); 
  static { 
            shareStrategies.put("height", new CatHeightComparator()); 
            ...
            ...
  }
复制代码




策略模式优缺点


  • 优点
  1. 算法策略可以自由切换
  2. 避免使用多重条件转移语句,如if...else...语句、switch 语句
  3. 策略模式符合开闭原则




  • 缺点
  1. 必须知道所有的策略,并且自行决定使用哪一个策略类。
  2. 代码中会产生非常多策略类,增加维护难度。



相关文章
|
7天前
|
设计模式 算法 PHP
php设计模式--策略模式(六)
php设计模式--策略模式(六)
10 0
|
3月前
|
设计模式 算法 搜索推荐
设计模式之策略模式
设计模式之策略模式
41 0
|
3月前
|
设计模式 算法 Java
行为型设计模式-策略模式(Strategy Pattern)
行为型设计模式-策略模式(Strategy Pattern)
|
3月前
|
设计模式 算法 Java
【设计模式】策略模式在数据接收和发送场景的应用
在数据接收和发送场景打算使用了if else进行判断。ASystem.sync("向A同步数据");BSystem.sync("向B同步数据");...非常麻烦,需求多了很臃肿!策略模式(Strategy Pattern)定义了一组同类型的算法,在不同的类中封装起来,每种算法可以根据当前场景相互替换,从而使算法的变化独立于使用它们的客户端(即算法的调用者)。// 创建两个策略对象// 创建上下文对象,并传入策略对象。
56 1
|
1月前
|
设计模式 算法 Java
【设计模式】策略模式
【设计模式】策略模式
|
3月前
|
设计模式 算法 自动驾驶
常见的设计模式(模板与方法,观察者模式,策略模式)
随着时间的推移,软件代码越来越庞大,随着而来的就是如何维护日趋庞大的软件系统。在面向对象开发出现之前,使用的是面向过程开发来设计大型的软件程序,面向过程开发将软件分成一个个单独的模块,模块之间使用函数进行组合,最后完成系统的开发,每次需要修改软件,如果不涉及好各个模块的关系,就会导致软件系统难以维护,从而导致软件变得不可使用。面向对象方法用对象模拟问题域中的实体,以对象间的联系刻画实体间联系
63 2
|
3月前
|
设计模式 算法
设计模式 | 策略模式
设计模式 | 策略模式
16 0
|
3月前
|
设计模式 算法 Go
Golang设计模式——15策略模式
Golang设计模式——15策略模式
25 0
|
3月前
|
设计模式 算法
设计模式之策略模式
设计模式之策略模式
|
3月前
|
设计模式 前端开发 算法
【设计模式】之策略模式
在前端开发中,我们经常会遇到需要根据不同的条件或情况来执行不同的算法或行为的情况。这时,策略模式就能派上用场。策略模式是一种行为型设计模式,它将不同的算法封装成独立的策略对象,使得这些算法可以互相替换,而不影响客户端代码。这种灵活性和可扩展性使得策略模式在前端开发中得到广泛应用。
45 0