问题的提出:一个问题,有其他各种不同的解决方法,如何让各种方法相互兼容。
单例模式的本质:使方法有相同的接口。
用来解决这个问题的一个合理方案就是策略模式(Strategy)。策略模式是指:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。这个模式使得算法可独立于使用它的客户而变化。
解决方案:首先抽象问题,一个问题,就相当于一个客户端所提供的问题接口,要让所有的解决方法可以解决同一个问题,这就需要解决同一个问题的方法都implement同一个接口,因为接口可以是拥有同一对外方法的抽象。所以让解决方法作为同一个接口的不同实现类,这样,当有新的解决方案出现时,就可以不改动以前的东西,只实现新的方案类。这样就可以解决维护和扩展的问题。
策略模式的实现结构图:
具体使用(java se中对战略这模式的使用):
(利用java.util.Comparator接口实现的策略模式,实现对扁平类,利用不同策略排序)
例如:对于POJO类 Dog,有时候需要对其按照体高排序,有时候需要对其按照重量排序,这样就需要多种排序策略,可以使用策略模式来解决此问题。(同样的问题还包括超市商品的不同销售策略,同类不同商品的不同处理等)
POJO类实现如下:
public class Dog implements Comparable{
private int dogId;
private String name;
private int height;
private int weight;
private Comparator comparator;
// constructor
public Dog(int dogId, String name, int height, int weight) {
this.dogId = dogId;
this.name = name;
this.height = height;
this.weight = weight;
}
// getters and setters generated by Eclipse
public int getDogId() {
return dogId;
}
public void setDogId(int dogId) {
this.dogId = dogId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public Comparator getComparator() {
return comparator;
}
public void setComparator(Comparator comparator) {
this.comparator = comparator;
}
@Override
public String toString() {
return "dog:" + dogId + "name|" + name + "height|" + height + "weight|" + weight;
}
@Override
public int compareTo(Object obj) {
if(obj instanceof Dog) {
return comparator.compare(this, (Dog)obj);
} else {
// if obj is not a dog, return -2 as error code
return -2;
}
}
}
Java.util.Comparator接口:
public interface Comparator {
public int compare(Object o1, Object o2);
}
对dog类不同的排序策略:
通过体高对dog进行进行排序,需要的策略:
public class HeightComparator implements Comparator {
@Override
public int compare(Object o1, Object o2) {
Dog d1 = (Dog)o1;
Dog d2 = (Dog)o2;
if(d1.getHeight() > d2.getHeight()) {
return 1;
} else if(d1.getHeight() < d2.getHeight()) {
return -1;
} else {
return 0;
}
}
}
通过体重对dog进行进行排序,需要的策略:
public class WeightComparator implements Comparator {
@Override
public int compare(Object o1, Object o2) {
Dog d1 = (Dog)o1;
Dog d2 = (Dog)o2;
if(d1.getWeight() > d2.getWeight()) {
return 1;
} else if(d1.getWeight() < d2.getWeight()) {
return -1;
} else {
return 0;
}
}
}
使用juint进行测试:
测试代码:
public class testStrategy {
private List<Dog> dogs = new ArrayList<Dog>();
@Before
public void addDogs() {
Dog d1 = new Dog(1,"dog1",1,4);
Dog d2 = new Dog(2,"dog2",3,2);
Dog d3 = new Dog(3,"dog3",5,5);
Dog d4 = new Dog(4,"dog4",2,3);
Dog d5 = new Dog(5,"dog5",4,1);
dogs.add(d1);
dogs.add(d2);
dogs.add(d3);
dogs.add(d4);
dogs.add(d5);
System.out.println("Dogs Before sort :");
print();
}
@Test
// test Weight Comparator
public void testWC() {
for(int i=0;i<dogs.size();i++) {
dogs.get(i).setComparator(new WeightComparator());
}
System.out.println("\nUsing Weight Comparator:");
Collections.sort(dogs);
print();
}
@Test
// test Height Comparator
public void testHC() {
for(int i=0;i<dogs.size();i++) {
dogs.get(i).setComparator(new HeightComparator());
}
System.out.println("\nUsing Height Comparator:");
Collections.sort(dogs);
print();
}
public void print() {
for(int i=0;i<dogs.size();i++) {
System.out.println(dogs.get(i));
}
}
}
测试结果:
Dogs Before sort :
dog:1name|dog1height|1weight|4
dog:2name|dog2height|3weight|2
dog:3name|dog3height|5weight|5
dog:4name|dog4height|2weight|3
dog:5name|dog5height|4weight|1
Using Weight Comparator:
dog:5name|dog5height|4weight|1
dog:2name|dog2height|3weight|2
dog:4name|dog4height|2weight|3
dog:1name|dog1height|1weight|4
dog:3name|dog3height|5weight|5
Using Height Comparator:
dog:1name|dog1height|1weight|4
dog:4name|dog4height|2weight|3
dog:2name|dog2height|3weight|2
dog:5name|dog5height|4weight|1
dog:3name|dog3height|5weight|5