Strategy策略模式是属于设计模式中对象行为型模式,主要是定义一系列的算法,把这些算法一个个封装成单独的类.我们达到了在运行期间,可以自由切换算法的目的。实际整个Strategy的核心部分就是抽象类(或者接口)的使用,使用Strategy模式可以在用户需要变化时,修改量很少,而且快速.一直有点糊涂的地方就是factory&strategy,实际上Strategy和Factory有一定的类似,Strategy相对简单容易理解,并且可以在运行时刻自由切换,Factory重点是用来创建对象。
设计模式就是把简单的东西复杂化,但是有理有据,看你将来在那个方向做扩展,那么就会在那个方向上复杂化,等等,农场生小母牛,那类与类之间的关系太简单了,感受不到系统之间的精妙的结构的乐趣.设计模式可以让你感受到这才是面向对象的乐趣精华所在!
设计模式笔记上的例子比较好,这里拿过来为以后的理解做铺垫。
TextStrategy是个抽象类,内含抽象方法:replace,linuxstrategy,windowsstrategy继承这个抽象类,同时各自实现方法replace,textCharChange调用textStrategy类中的replace方法进行使用,
TextStrategy抽象类的结构:
public abstract classTextStrategy {
protected String text;
public TextStrategy(String text) {
this.text = text;
}
public abstract String replace();
}
Linux的实现策略:
public classLinuxStrategy extends TextStrategy {
publicLinuxStrategy(String text) {//构造方法
super(text);
}
public String replace() {//实现的具体方法,这才是核心
preOperation();
System.out.println(text =text.replaceAll("@r@n", "@n"));
postOperation();
return text;
} }
Windows实现策略:
public classWindowsStrategy extends TextStrategy {
public WindowsStrategy(String text) {
super(text);
}
public String replace() {
startOperation();
System.out.println(text =text.replaceAll("@n", "@r@n"));
endOperation();
return text;
}}
整合在一起使用的类:
public classTextCharChange {
public static voidreplace(TextStrategy strategy) {//传策略的参数,直接调用,这儿很巧妙!!
strategy.replace();
} }
测试类:
public class Main {
public static void main(String[] args) {
String linuxText = "This is a test text!!@n Oh! LineReturn!!@n";
String windowsText = "This is atest text!!@r@n Oh! Line Return@r@n";
TextCharChange.replace( new WindowsStrategy(linuxText));//直接调用就行!
System.out.println();
TextCharChange.replace( newLinuxStrategy(windowsText));
}}
strategy模式的结构图,三个具体策略的实现类,一个抽象类或接口,另外一个整合使用的类,直接调用整合后的类即可~~
以上是strategy模式笔记比较简单的用法,但是看sp学习的话,马老师给出了一个很复杂的例子,有点迷糊,没具体操作。。下次再写吧,或者就不写了,其实也很简单,他的流程是这样的:
首先用一般的sort方法,想着sort的复用而让需要排序的类:cat,dag实现comparable接口,实现comparTo方法,通过这个方法对这个类的两个对象比较大小,为了实现对同一类的不同属性的大小的比较,而对每个类生成多个比较策略类:CatHeightComparator,CatWeightComparator,这两个比较策略使用时可以随时调用。
分析了下sp中讲到的例子,对cat对象比较大小,总共有两个接口:comparable,comparator,其中comparable中方法为:compareTo(0),comparator方法:compare(0,0),cat实现了comparable接口,实现compareTo()方法时,使用了compartor.compare()方法,及动态调用需要用到的比较策略:heighe,or weighte比较策略。HeightCompare,WeightCompare都实现了compartor接口,实现了compare方法。dataSorter类对数组中的所有对象进行sort操作。test是测试类。
具体代码如下:
两个接口的就省了,写cat的实现:
public class Catimplements java.lang.Comparable<Cat> {
privateint height;
privateint weight;
//privateComparator comparator = new CatHeightComparator();
privatejava.util.Comparator<Cat> comparator = new CatHeightComparator();//此处已经赋值了,不如第一个例子中的给的动态性强
public Cat(Comparator comparator, int height, int weight) {//这样就可以了。。
super();
this.comparator = comparator;
this.height = height;
this.weight = weight;
}
@Override
publicString toString() {//便于对象的输出,若没有的话,只会输出对象在内存中的引用,是一串引用代码;
returnheight + "|" + weight;}
@Override
publicint compareTo(Cat o) {//调用comparator的compare方法,这里如上一个例子中的textChartChange中的replace方法一样,但是此处调用不很灵活
return comparator.compare(this, o);//可以再为对像初始化时,传一个比较器接口,然后进行比较~
}}HeightCompare实现:weightCompare省掉。
public classCatHeightComparator implements java.util.Comparator<Cat> {
@Override
publicint compare(Cat o1, Cat o2) {//真正比较策略的实现,将方法封装成类,方便动态调用而不用该代码;
Catc1 = (Cat)o1;
Catc2 = (Cat)o2;
if(c1.getHeight()> c2.getHeight()) return 1;
elseif(c1.getHeight() < c2.getHeight()) return -1;
return0;
}}
DataSort实现:
public classDataSorter {
public static voidsort(Object[] a) {
for(inti=a.length; i>0; i--) {
for(intj=0; j<i-1; j++) {
Comparableo1 = (Comparable)a[j];
Comparableo2 = (Comparable)a[j+1];
if(o1.compareTo(o2)== 1) {//真正用的地方!实际上,compareTo方法调用了cat内的comparetor对象的compare方法;
swap(a,j , j+1);//工具方法
}}}}
privatestatic void swap(Object[] a, int x, int y) {//注意参数的传递,此处要有数组a ,不然起不到换位置的作用!
Objecttemp = a[x];
a[x]= a[y];
a[y]= temp;}
}
Test类实现:
public class Test {
publicstatic void main(String[] args) {
Cat[] c = { new Cat(new CatWeightComparator(), 1, 2),//动态传比较的属性值过来,这样就可以了!
new Cat(new CatWeightComparator(), 27, 1),
new Cat(new CatWeightComparator(), 22, 3) };
DataSorter.sort(a);//直接调用dataSorter的sort方法,sort中调用comparable对象的compareTo方法,compareTo方法实际上调用的是comparable对象中comparetor对象的compare()方法,所以真正实现在comparetor实现类的compare方法中!
DataSorter.p(a);//打印出结果
}}
这个比上面那个例子复杂在:cat本身也是一个实现了comparable接口的类,这样就跟compartor有点混淆了!其实真正的含义有两点:
1.实现comparable对象的比较,并且做到datasort sortor方法的可重用性;
2.对同一comparable对象的不同比较方法的实现,并且用动态调用的方式使用;(当然这里面没有例子以做的好,因为compartor对象是写死在cat类里的,最好的是在使用时,通过参数传过来!)
3.与State一样,例子中完美的面向对象的思维,用TextCharChange完美的把接口及其实现封装起来,用的时候直接提供TextCharChange就行!赞一个!!而且方法名称都一样:replace.不会像后面那个例子那样容易混淆!当然后面的例子也有他的原因,因为他是要封装整个DataSorter类及其sorter方法达到最好的复用性,所以首先要对外提供一个comparable的接口的参数传递,使得实现这个接口的所有的类都能调用这个方法进行sort,然后就涉及到,实现类可以调用方法进行比较了,但是真正的比较过程与简单的数据类型又不相同,因为是类的比较,有会考虑比较那个属性?为了提供更好的多态或者扩展性,就要对外提供一个很比较方法的策略参数的传值:CatWeightCompartor()类实现了对重量的比较的策略,所以传递这个类的对象可以实现这种比较策略,同理,相同的策略是要实现于统一的接口的,才能保证被接受这个参数的方法使用!所以,catweightcompartor实现了compartor接口!
所以,仔细分析才知道,实际上是有两层策略(sort,compareTo),每一层的使用都会用到接口.sort为了实现对comparable的对象的比较,comparTo为了实现对同一对象的多种不同的比较方式!