策略模式
开闭原则:对修改关闭,对扩展开放
一、示例
首先写一个自己的Comparator方法(也可以用java的,这里先自己写)
然后传递函数的时候先传递一个T类型的数组,然后再传递一个比较器,这个比较器用来说明这个类型如何比较(好处是可以是不同类的比较器,也可以是同一类的不同属性的比较器)
首先写一个比较器,这里用了泛型
1 2 3 4 5
| package strategy;
public interface Comparator<T> { int compare(T o1, T o2) }
|
然后写个示例类,比如Dog类
1 2 3 4 5 6 7 8 9 10 11 12 13
| package strategy;
public class Dog { int food; Dog(int a){food = a;}
@Override public String toString() { return "Dog{" + "food=" + food + '}'; } }
|
然后写这个Dog类的比较器,Override比较器里的compare方法,对food的大小进行比较
1 2 3 4 5 6 7 8
| public class DogComparator implements Comparator<Dog>{ @Override public int compare(Dog o1, Dog o2) { if(o1.food < o2.food) return -1; else if(o1.food >o2.food) return 1; else return 0; } }
|
然后是比较函数Sorter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package strategy;
public class Sorter<T> { public void sort(T[] arr, Comparator<T> comparator){ for(int i=0; i<arr.length; 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; } }
|
最后在Main里进行测试
1 2 3 4 5 6 7 8 9 10 11 12
| package strategy;
import java.util.Arrays;
public class Main { public static void main(String[] args) { Dog[] a = {new Dog(3), new Dog(2), new Dog(1)}; Sorter<Dog> sorter = new Sorter<>(); sorter.sort(a,new DogComparator()); System.out.println(Arrays.toString(a)); } }
|
二、考虑如何把策略模式应用到工程里
例子是坦克射子弹,老师给的代码太复杂,我简化了一些:
首先是**FireStrategy
** 接口
1 2 3 4 5
| package tank;
public interface FireStrategy { void fire(Tank t); }
|
DefaultFireStrategy
和 FourDirFireStrategy
分别是实现了这个接口的具体策略类
1 2 3 4 5 6 7 8
| package tank;
public class DefaultFireStrategy implements FireStrategy{ @Override public void fire(Tank t) { System.out.println("默认开火方法"); } }
|
1 2 3 4 5 6 7 8
| package tank;
public class FourDirFireStrategy implements FireStrategy{ @Override public void fire(Tank t) { System.out.println("四个方向开火"); } }
|
Tank
类则持有一个 FireStrategy
引用,可以在运行时根据需要切换不同的开火策略
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package tank;
public class Tank { private FireStrategy fireStrategy;
public Tank() { this.fireStrategy = new DefaultFireStrategy(); }
public void setFireStrategy(FireStrategy fireStrategy) { this.fireStrategy = fireStrategy; }
public void fireOutput() { fireStrategy.fire(this); } }
|
最后是main方法测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package tank;
public class Main { public static void main(String[] args) { Tank tank = new Tank();
tank.fireOutput();
tank.setFireStrategy(new FourDirFireStrategy()); tank.fireOutput(); } }
|