策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。引用其他人的解释:
策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
示范代码工程:
示范工程实现的是 对不同的动物根据动物的属性进行排序,既然是排序,先确定独立的排序算法(基于冒泡排序):
package test.edu.sort;
import test.edu.animal.IAnimalCompareable;
public class SortList {
public static <E> void sort(IAnimalCompareable<E>[] obList ){
IAnimalCompareable<E> temp;
for(int i=0;i<obList.length-1;i++){
for(int j=i+1;j<obList.length;j++){
if(obList[i].compareTo(obList[j])>0){
temp=obList[i];
obList[i]=obList[j];
obList[j]= temp;
}
}
}
}
}
定义 IAnimalCompareable 泛型接口 和IAnimalComparator 泛型接口:
package test.edu.animal;
public interface IAnimalComparable<E> {
public int compareTo(IAnimalCompareable<E> ob);
}
package test.edu.animal;
public interface IAnimalComparator<E> {
public int compare(IAnimalCompareable<E> o1,IAnimalCompareable<E> o2);
}
想对猫根据重量进行排序,则定义Cat实现IAnimalComparable接口
package test.edu.animalimpl;
import test.edu.animal.IAnimalComparator;
import test.edu.animal.IAnimalComparable;
public class Cat implements IAnimalComparable<Cat> {
private int weight;
public Cat(int weight) {
this.weight = weight;
}
@Override
public int compareTo(IAnimalComparable<Cat> ob) {
IAnimalComparator<Cat> catc = new CatComparator();
return catc.compare(this, ob);
}
public int getWeight() {
return weight;
}
}
实现比较器接口,定义具体用什么属性如何比较:
package test.edu.animalimpl;
import test.edu.animal.IAnimalComparator;
import test.edu.animal.IAnimalComparable;
public class CatComparator implements IAnimalComparator<Cat> {
@Override
public int compare(IAnimalComparable<Cat> o1, IAnimalComparable<Cat> o2) {
// TODO Auto-generated method stub
if(((Cat) o1).getWeight() > ((Cat) o2).getWeight()){
return 1;
}
return 0;
}
}
同理 如何需要对狗根据高度进行排序:
package test.edu.animalimpl;
import test.edu.animal.IAnimalComparator;
import test.edu.animal.IAnimalComparable;
public class Dog implements IAnimalComparable<Dog> {
private int heigh;
public int getHeigh() {
return heigh;
}
public Dog(int heigh) {
this.heigh = heigh;
}
@Override
public int compareTo(IAnimalComparable<Dog> ob) {
IAnimalComparator<Dog> dogc = new DogComparator();
return dogc.compare(this, ob);
}
}
实现比较器接口,定义具体用什么属性如何比较:
package test.edu.animalimpl;
import test.edu.animal.IAnimalComparator;
import test.edu.animal.IAnimalComparable;
public class DogComparator implements IAnimalComparator<Dog> {
@Override
public int compare(IAnimalComparable<Dog> o1, IAnimalComparable<Dog> o2) {
if(((Dog) o1).getHeigh()> ((Dog) o2).getHeigh()){
return 1;
}
return 0;
}
}
package test.edu.sortanimal;
import test.edu.animalimpl.Cat;
import test.edu.animalimpl.Dog;
import test.edu.sort.SortList;
public class SortClient {
public static void main(String[] args){
//对猫根据重量进行排序
Cat[] cats={new Cat(10),new Cat(20),new Cat(5),new Cat(30),new Cat(15),new Cat(7)};
SortList.sort(cats);
System.out.println("====对猫根据重量排序后====");
for(Cat c:cats){
System.out.println(c.getWeight());
}
//对狗根据高度进行排序
Dog[] dogs={new Dog(10),new Dog(20),new Dog(5),new Dog(30),new Dog(15),new Dog(7)};
SortList.sort(dogs);
System.out.println("====对狗根据高度排序后====");
for(Dog c:dogs){
System.out.println(c.getHeigh());
}
}
}
测试结果:
====对猫根据重量排序后====
5
7
10
15
20
30
====对狗根据高度排序后====
5
7
10
15
20
30
==以下引用自别人的博文=
策略模式的重心
策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。
算法的平等性
策略模式一个很大的特点就是各个策略算法的平等性。对于一系列具体的策略算法,大家的地位是完全一样的,正因为这个平等性,才能实现算法之间可以相互替换。所有的策略算法在实现上也是相互独立的,相互之间是没有依赖的。
所以可以这样描述这一系列策略算法:策略算法是相同行为的不同实现。
运行时策略的唯一性
运行期间,策略模式在每一个时刻只能使用一个具体的策略实现对象,虽然可以动态地在不同的策略实现中切换,但是同时只能使用一个。
公有的行为
经常见到的是,所有的具体策略类都有一些公有的行为。这时候,就应当把这些公有的行为放到共同的抽象策略角色Strategy类里面。当然这时候抽象策略角色必须要用Java抽象类实现,而不能使用接口。
这其实也是典型的将代码向继承等级结构的上方集中的标准做法。
策略模式的优点
(1)策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。
(2)使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。
策略模式的缺点
(1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。
(2)由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。