策略模式:
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。
如何解决:将这些算法封装成一个一个的类,任意地替换。
关键代码:实现同一个接口。
上面都是官方的解释,下面来个例子说明什么是策略模式
比如一组数组是int类型的,需要进行排序,你啪啪啪写好代码,这时候又来了一个数组是double类型的,你又啪啪啪写好代码,你会发现两个代码之间有很多的冗余,区别只是数据类型不同,这个时候如果又来了新需求,说要排序猫和排序狗,猫按重量来排序,狗按食量来排序,这时候完蛋了,代码越写越多,越写越乱。这个时候就需要使用策略模式了。
首先定义个接口,里面定义一个比较方法
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
default void m() {
System.out.println("m");
}
}
之后在定义猫类的时候实现接口
public class Cat implements Comparable<Cat> {
int weight, height;
public Cat(int weight, int height) {
this.weight = weight;
this.height = height;
}
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 +
'}';
}
}
狗中也实现接口
public class Dog implements Comparable<Dog> {
int food;
public Dog(int food) {
this.food = food;
}
@Override
public int compareTo(Dog d) {
if(this.food < d.food) return -1;
else if(this.food > d.food) return 1;
else return 0;
}
@Override
public String toString() {
return "Dog{" +
"food=" + food +
'}';
}
}
排序方法
public class Sorter<T> {
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);
}
}
//sort(int)
void swap(T[] arr, int i, int j) {
T temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
测试
public class Main {
public static void main(String[] args) {
//int[] a = {9, 2, 3, 5, 7, 1, 4};
Cat[] a = {new Cat(3, 3), new Cat(5, 5), new Cat(1, 1)};
//Dog[] a = {new Dog(3), new Dog(5), new Dog(1)};
Sorter<Cat> sorter = new Sorter<>();
sorter.sort(a, (o1, o2)->{
if(o1.weight < o2.weight) return -1;
else if (o1.weight>o2.weight) return 1;
else return 0;
});
System.out.println(Arrays.toString(a));
}
}
输出
[Cat{weight=1, height=1}, Cat{weight=3, height=3}, Cat{weight=5, height=5}]