摘要
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
介绍
意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。
如何解决:将这些算法封装成一个一个的类,任意地替换。
关键代码:实现同一个接口。
应用实例: 1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。 2、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。
优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。
使用场景: 1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。 2、一个系统需要动态地在几种算法中选择一种。 3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。
实现一(算法)
定义两个int属性的值得加、减、乘的方法,使用策略模式实现获得结果。
定义策略接口
public interface Strategy {
int doOperation(int num1, int num2);
}
接口的实现
public class OperationAdd implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
public class OperationSubtract implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
public class OperationMultiply implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 * num2;
}
}
定义策略方法
public class UseStrategyContext {
public static int operating(int num1, int num2, Strategy strategy){
return strategy.doOperation(num1, num2);
}
}
策略的使用
public class Main {
public static void main(String[] args) {
int num1 = 3;
int num2 = 5;
int result = UseStrategyContext.operating(num1, num2, new OperationMultiply());
System.out.println("乘结果:" + result);
result = UseStrategyContext.operating(num1, num2, new OperationAdd());
System.out.println("加结果:" + result);
result = UseStrategyContext.operating(num1, num2, new OperationSubtract());
System.out.println("减结果:" + result);
}
}
实现二(行为——结合泛型)
定义猫,狗两个类,分别以体重或身高或者年龄进行比较,使用策略模式实现。
public class Animal {
private Integer weight;
private Integer height;
private Integer age;
public Animal(Integer weight, Integer height, Integer age) {
this.weight = weight;
this.height = height;
this.age = age;
}
public Integer getWeight() {
return weight;
}
public void setWeight(Integer weight) {
this.weight = weight;
}
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "{" +
"weight=" + weight +
", height=" + height +
", age=" + age +
'}';
}
}
public class Cat extends Animal{
public Cat(Integer weight, Integer height, Integer age) {
super(weight, height, age);
}
@Override
public String toString() {
return "Cat " + super.toString();
}
}
public class Dog extends Animal{
public Dog(Integer weight, Integer height, Integer age) {
super(weight, height, age);
}
@Override
public String toString() {
return "Dog " + super.toString();
}
}
定义策略接口
public interface Comparer<T> {
int compareTo(T o1, T o2);
}
接口的实现
import com.jiangbo.design_mode.strategy.normal.Animal;
public class AgeComparer<T extends Animal> implements Comparer<T>{
@Override
public int compareTo(T o1, T o2) {
if(o1.getAge() > o2.getAge()) return 1;
else if(o1.getAge() < o2.getAge()) return -1;
else return 0;
}
}
import com.jiangbo.design_mode.strategy.normal.Animal;
public class HeightComparer<T extends Animal> implements Comparer<T>{
@Override
public int compareTo(T o1, T o2) {
if(o1.getHeight() > o2.getHeight()) return 1;
else if(o1.getHeight() < o2.getHeight()) return -1;
else return 0;
}
}
import com.jiangbo.design_mode.strategy.normal.Animal;
public class WeightComparer<T extends Animal> implements Comparer<T>{
@Override
public int compareTo(T o1, T o2) {
if(o1.getWeight() > o2.getWeight()) return 1;
else if(o1.getWeight() < o2.getWeight()) return -1;
else return 0;
}
}
定义策略方法、
public class MySort2<T> {
/**
* 冒泡排序
* @param objects
* @param comparer
*/
public void sort(T[] objects, Comparer<T> comparer){
for (int i = 0; i < objects.length; i++) {
for (int j = i+1; j < objects.length; j++) {
if(comparer.compareTo(objects[i], objects[j]) > 0){
T temp = objects[i];
objects[i] = objects[j];
objects[j] = temp;
}
}
}
}
}
策略的使用
import com.jiangbo.design_mode.strategy.normal.Cat;
import com.jiangbo.design_mode.strategy.normal.Dog;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Cat[] cats = {new Cat(30, 40, 5), new Cat(25, 35, 3), new Cat(35, 45, 4)};
// new MySort2<Cat>().sort(cats, new HeightComparer<>());
new MySort2<Cat>().sort(cats, new WeightComparer<>());
// new MySort2<Cat>().sort(cats, new AgeComparer<>());
System.out.println(Arrays.toString(cats));
Dog[] dogs = {new Dog(30, 40, 5), new Dog(25, 35, 3), new Dog(35, 45, 4)};
// new MySort2<Dog>().sort(dogs, new HeightComparer<>());
new MySort2<Dog>().sort(dogs, new WeightComparer<>());
// new MySort2<Dog>().sort(dogs, new AgeComparer<>());
System.out.println(Arrays.toString(dogs));
}
}