策略模式
策略模式:一个类的行为或者方法可以在运行时改变。这种类型的设计模式属于行为型模式。
就是当一个用户在调用某个对象的同一个方法时,希望该方法能随着执行业务不同而改变不同的执行方式。
Java中常用的策略模式:java.lang.Comparator
接口
需求:
当前有一个用户需要给他管理的猫进行排序,且排序策略均不相同。
有按照年龄排序,有按照体重排序等等
Cat类
package com.liqk.strategy;
public class Cat {
private String name;
private int age;
private double weight;
public Cat(String name, int age, double weight) {
this.name = name;
this.age = age;
this.weight = weight;
}
//省略get和Set方法
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
", age=" + age +
", weight=" + weight +
'}';
}
}
用户自定义比较策略
package com.liqk.strategy;
import java.util.Arrays;
public class User {
public static void main(String[] args) {
//初始化待比较的小猫
Cat[] cats = {new Cat("吉鲁",4,4.7),
new Cat("加菲",3,3.9),
new Cat("汉达",1,1.4),
new Cat("库鲁",5,5.2),
new Cat("阿尔法",2,3.2)};
//调用javaAPI 对cats进行快速排序 --需要传入不同的策略来执行排序
//使用Lambda快速实现Comparator接口 如该策略会使用多次 建议使用实现类实现
//根据年龄 按照从小到大排序
Arrays.sort(cats, (c1,c2)->Integer.compare(c1.getAge(),c2.getAge()));
System.out.println(Arrays.toString(cats));
//根据体重 按照从重到轻排序
Arrays.sort(cats,(c1,c2)->-Double.compare(c1.getWeight(),c2.getWeight()));
System.out.println(Arrays.toString(cats));
}
}
执行结果:
[Cat{name='汉达', age=1, weight=1.4}, Cat{name='阿尔法', age=2, weight=3.2}, Cat{name='加菲', age=3, weight=3.9}, Cat{name='吉鲁', age=4, weight=4.7}, Cat{name='库鲁', age=5, weight=5.2}]
[Cat{name='库鲁', age=5, weight=5.2}, Cat{name='吉鲁', age=4, weight=4.7}, Cat{name='加菲', age=3, weight=3.9}, Cat{name='阿尔法', age=2, weight=3.2}, Cat{name='汉达', age=1, weight=1.4}]
其中java.lang.Comparator
接口 就是应用策略模型的接口
public interface Comparator<T> {
//该类只封装执行方法的声明,谁使用谁实现,保证策略随需求变化
int compare(T o1, T o2);
}
设计思想
当使用者要根据不同的需求来决定要执行某个功能时。
可以创建一个接口,该接口定义了具体功能的抽象方法。
之后创建不同的策略(实现类)来实现该接口中的具体功能。每个实现类都可以看做一个策略,使用时根据需求任意替换。
使用者调只需要根据需求传入不同的策略类即可(参数列表声明时需要使用接口类型–多态性)
优点:
- 算法可以自由切换。
- 避免使用多重条件判断。
- 扩展性良好。
缺点:
- 策略类会增多。
- 所有策略类都需要对外暴露。
应用实例:
- 诸葛亮的锦囊妙计,每一个锦囊就是一个策略。
- 旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。
- 飞机游戏中,飞机可以一次发射一个子弹,一次发射多个子弹,可以多个方向发射子弹,每种射击方式就是一个策略。
使用场景:
- 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
- 一个系统需要动态地在几种算法中选择一种。
- 如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
注意事项:
如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。