思路
在开发中,我们会遇到多个算法或者策略,来实现不同的行为。我们根据环境和需求要实现不同的策略活着好算法。比如说,对对象的排序,一个对象有多个属性,我们定义一个算法,根据这个对象的某个属性来排序,假如有一天需求变更,根据这个属性的另外一个属性来排序。那么我们可能我们设计好的算法也要进行变更,这显然扩展性不好,不利于维护。
策略
在实际开发中,我们需要把算法和对象分开来。让对象自身具备某个比较的实现,而我们自己设计的算法不再需要进行变更,这显然使我们刚加希望的实现。让程序按照我们的策略进行实现,而不用更改我们的算法,让他们可以互相转换。
模拟JAVA中的Comparable和Comparator的策略
package com.strategy;
public interface Comparable {
public int compareTo(Object o);
}
----------
//Comparator
package com.strategy;
public interface Comparator<T> {
int compare(T o,T j);
}
----------
//策略比较
package com.strategy;
public class HeightComparetor implements Comparator<Cat>{
public int compare(Cat o, Cat j) {
if(o.getHeight() > j.getHeight()) return 1;
if(o.getHeight() < j.getHeight()) return -1;
return 0;
}
}
----------
//Cat类
package com.strategy;
public class Cat implements Comparable{
private int height;
private int width;
//高度比较器
HeightComparetor comparetor = new HeightComparetor();
public Cat(int height, int width) {
super();
this.height = height;
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
@Override
public int compareTo(Object o) {
//这是之前采用的compareTo比较,而后采用高度比较器的策略模式,对于想用其他进行比较,只要在做Conparator的实现即可,而程序不用整个更改
/*Cat cat = (Cat)o;
if(this.getHeight() > cat.getHeight()) return 1;
if(this.getHeight() < cat.getHeight() ) return -1;*/
return comparetor.compare(this, (Cat)o);
}
@Override
public String toString() {
return "Cat [height=" + height + ", width=" + width + "]";
}
}
----------
//算法
package com.strategy;
public class Sorter {
//在这里,我们的算法不需要更改
public static void sort(Cat[] a) {
for(int i = a.length;i > 0;i--){
for(int j =0; j < i - 1;j++){
Comparable co = a[j];
Comparable to = a[j+1];
if(co.compareTo(to) == 1){
swap(a,j,j+1);
}
}
}
}
private static void swap(Cat[] a, int i, int j) {
// TODO Auto-generated method stub
Cat temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void p(Cat[] a) {
for(int i = 0;i < a.length;i++){
System.out.print(a[i]+" ");
}
System.out.println();
}
}
----------
public static void main(String[] args) {
Cat[] a = {new Cat(3,2),new Cat(2,5)};
Sorter.sort(a);
Sorter.p(a);
}
----------
//Console
Cat [height=2, width=5] Cat [height=3, width=2]
优缺点
优点:我们的程序的算法重用性提高,只需要不同的策略实现就可以实现我们算法的互相转换。在开发中,随着一系列行为的堆砌,不同的行为又具备不同的特点,这一点上我们的算法总不能因为行为的增加而去为每个行为都设计一个算法吧。在一定情况下,也减轻了if else的出现,我们可以选择不同的实现来为算法匹配。
缺点:不同的行为就要实现不同的策略,就意味着我们的程序会有很多的策略,而我们在使用的时候,对于客户而言可能不知道某个策略的具体实现,同时也会把策略暴露在别人面前。而同时,我们的策略是按照我们定义的相同的接口实现的,而有时简单的策略 的初始化,我们可能并不用到全部,而里面某些参数却已经初始化的,这显然增加了通信开销。而一旦存在这种问题,就要让接口和策略进行紧耦合。
总结
右上面的模拟可以看见,策略模式的好处是,我们程序中的算法不需要进行更改,只需要对对象的某种策略进行比较,并且不影响算法的情况下,依然可以运行下去。,这就是策略模式