策略模式
策略模式指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。为了让这些算法可以相互替换。因此为这一系列算法定义公共的接口,用来约束这一系列算法要实现的功能。若这一系列算法具有公共功能,可以把策略接口实现为抽象类,把这些公共部分的功能实现到父类里面。
-
比如
- 每个人都要“交个人所得税”,但是“在美国交个人所得税”和“在中国交个人所得税”就有不同的算税方法。
- 旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。
- 联系他人 ,选择打电话、qq 、微信。
-
策略模式:
- 定义了一族算法(业务规则);
- 封装了每个算法;
- 这族的算法可互换代替(interchangeable)
-
策略模式的优缺点;
- 避免多重条件语句:策略模式的一系列策略算法是平等的,可以互换的,写在一起就是通过if-else结构来组织,如果此时具体的算法实现里面又有条件语句,就构成了多重条件语句,使用策略模式能避免这样的多重条件语句。
- 有更好的扩展性
- 增加了对象数目:由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很多。
- 只适合扁平的算法结构:策略模式的一系列算法地位是平等的,是可以相互替换的,事实上构成了一个扁平的算法结构,也就是在一个策略接口下,有多个平等的策略算法,就相当于兄弟算法。而且在运行时刻只有一个算法被使用,这就限制了算法使用的层级,使用的时候不能被嵌套使用。
-
实现策略模式
- 定义一个接口
package 策略模式; public interface Comparable<T> { int comparableTo(T t); }
-
接口实现类
package 策略模式; public class Cat implements Comparable<Cat>{ private int age; public Cat(int age) { this.age = age; } @Override public int comparableTo(Cat cat) { if(this.age < cat.age) return -1; else if(this.age>cat.age)return 1; else return 0; } @Override public String toString() { return "Cat{" + "age=" + age + '}'; } } --------------------------------------------------------------------------- package 策略模式; public class Dog implements Comparable<Dog>{ private int id; public Dog(int id) { this.id = id; } public int comparableTo(Dog dog) { if(this.id < dog.id) return -1; else if(this.id>dog.id)return 1; else return 0; } @Override public String toString() { return "Dog{" + "id=" + id + '}'; } }
-
业务方法
package 策略模式; import java.util.Arrays; public class Sorter { public void sort(Comparable[] arr){ for (int i = 0; i < arr.length-1; i++) { int minObj= i ; for (int j = i+1; j < arr.length; j++) { minObj = arr[j].comparableTo(arr[minObj]) == -1 ? j : minObj; } swap(arr, i ,minObj); } } static void swap(Comparable[] arr, int i ,int j){ Comparable temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } }
-
测试
package 策略模式; import java.util.Arrays; public class Main { public static void main(String[] args) { Cat[] arr = {new Cat(2),new Cat(1), new Cat(5) }; Dog[] arr1= {new Dog(10),new Dog(8),new Dog(6)}; Sorter sorter = new Sorter(); sorter.sort(arr); sorter.sort(arr1); System.out.println(Arrays.toString(arr)+"---------"+Arrays.toString(arr1)); } }