一、策略模式概述
模式定义: 定义算法族,分别封装一起,让它们可以相互替换;此模式让算法的变化独立于使用它的客户
使用场景: 针对一个问题有多种解决方法,而区别仅仅在于算法(行为)不同
模式结构:
1.抽象策略类
定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
2.具体策略类
实现了抽象策略定义的接口,提供具体的算法实现。
3.环境类
持有一个抽象策略类的引用,最终给客户端调用。
UML图:
二、标准策略代码实现
/**
* 抽象策略类
*/
public interface IStrategy {
int calculate(int num1, int num2);
}
/**
* 具体实现类A
*/
public class AddStrategy implements IStrategy {
@Override
public int calculate(int num1, int num2) {
System.out.println("加法");
return num1 + num2;
}
}
/**
* 具体实现类B
*/
public class MinusStrategy implements IStrategy {
@Override
public int calculate(int num1, int num2) {
System.out.println("减法");
return num1 - num2;
}
}
/**
* 环境类(持有策略抽象类)
*/
public class Context {
private IStrategy cal;
public Context(IStrategy cal) {
this.cal = cal;
}
public int excuteCalculate(int num1, int num2) {
return cal.calculate(num1, num2);
}
}
测试结果
public class ClientMain {
public static void main(String[] args) {
Context context = new Context(new AddStrategy());
int result = context.excuteCalculate(30, 20);
System.out.println(result);
}
}
三、模式理解重点
策略模式的重心不是如何实现算法,而是如何组织这些算法,从而让程序结构更加灵活,具有更好的维护性和扩展性。
判断是不是策略模式,只要看一个类里是否持有了抽象对象的关联或者依赖,且当客户使用这个类使用实例化了这个属性。
四、策略模式java用例
1.Comparator的使用
java中比较的使用就是典型的策略模式,我们实例化了Comparator(抽象策略类)接口传递给TreeSet(环境类)。
TreeSet<Person> treeSet=new TreeSet<>(new Comparator<Person>(){
@Override
public int compare(Person o1, Person o2) {
return o1.getAge()-o2.getAge();
}
});
查看源码可以发现TreeSet间接持有了Comparator对象
public class TreeSet<E> extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, java.io.Serializable
{
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
}
public class TreeMap<K,V> extends AbstractMap<K,V>
implements NavigableMap<K,V>, Cloneable, java.io.Serializable
{
private final Comparator<? super K> comparator;
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}
}
2.Arrays.sort()中Comparator的使用
Arrays.sort(null, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge()-o2.getAge();
}
});
查看源码可以发现Arrays虽然没有持有Comparator对象,而是通过静态方法执行,但是思想上还是使用策略模式
public static <T> void sort(T[] a, Comparator<? super T> c) {
if (c == null) {
sort(a);
} else {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, c);
else
TimSort.sort(a, 0, a.length, c, null, 0, 0);
}
}
五、变通
根据实际使用策略模式也并非一成不变,只要是使用了策略思想都可以归为该模式;下面这种方式是环境类持有抽象类的依赖。
/**
* 环境类(持有策略抽象类)
*/
public class Context {
public static int excuteCal(IStrategy cal,int num1,int num2){
return cal.calculate(num1,num2);
}
}
**测试结果**
public class ClientMain {
public static void main(String[] args) {
int result = Context.excuteCal(new AddStrategy(),30,20);
System.out.println(result);
}
}
//TODO
六、心得参考
http://c.biancheng.net/view/1378.html
https://blog.csdn.net/u012124438/article/details/70039943/
HeadFirst设计模式
网友评论