您的位置:首页 > 编程语言 > Java开发

【Java设计模式】(2)策略模式Strategy

2015-01-04 20:17 716 查看
文章出处:/article/1876438.html

1. 自己实现排序打印方法

我们先来写这样一个类,它提供了给int数组排序和打印的方法:

package com.thr.strategy;

public class DataSorter {

	public static void sort(int[] array) {
		for (int i = array.length - 1; i >= 0; i--) {
			for (int j = 0; j < i; j++) {
				if (array[j] > array[j + 1]) {
					swap(array, j, j + 1);
				}
			}
		}
	}

	private static void swap(int[] array, int x, int y) {
		int temp = array[x];
		array[x] = array[y];
		array[y] = temp;
	}

	public static void pritn(int[] array) {
		for (int i = 0; i < array.length; i++) {
			System.out.println(array[i]);
		}
	}

}
如果我们需要的是对double型数组排序呢?可以,粘贴复制一份,使用重载就行了。要是float呢?一样。
如果是这样一个自己定义的类呢?

package com.thr.strategy;

public class Cat {

	private int height;
	private int weight;

	public Cat(int height, int weight) {
		super();
		this.height = height;
		this.weight = weight;
	}

	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;
	}

	@Override
	public String toString() {
		return "Cat [height=" + height + ", weight=" + weight + "]";
	}

}
要是用height来比较的话,增加DataSorter代码:

public static void sort(Cat[] array) {
		for (int i = array.length - 1; i >= 0; i--) {
			for (int j = 0; j < i; j++) {
				if (array[j].getHeight() > array[j + 1].getHeight()) {
					swap(array, j, j + 1);
				}
			}
		}
	}

	private static void swap(Cat[] array, int x, int y) {
		Cat temp = array[x];
		array[x] = array[y];
		array[y] = temp;
	}

	public static void pritn(Cat[] array) {
		for (int i = 0; i < array.length; i++) {
			System.out.println(array[i].toString());
		}
	}
那么问题就来了,如果将来要拿dog来排序,再后来pig也需要排序等等。。。这样做是不是不妥了呢?

这是我们就要考虑使用接口了(当程序想要扩展是,第一个应当想到多态)!

2. 创建接口Comparable

于是我们定义这样一个接口,它用来规定类之间比较的规则:

package com.thr.strategy;

public interface Comparable {
	int compareTo(Object o);
}
将Cat类实现Comparable接口,这次我们用体重比较大小,增加方法compareTo:

@Override
	public int compareTo(Object o) {
		if (o instanceof Cat) {
			Cat c = (Cat) o;
			if (getWeight() > c.getWeight()) {
				return 1;
			} else if (getWeight() < c.getWeight()) {
				return -1;
			} else {
				return 0;
			}
		} else {
			return -2;
		}
	}
最后修改DataSorter类:

package com.thr.strategy;

public class DataSorter {

	public static void sort(Object[] a) {
		for (int i = a.length; i > 0; i--) {
			for (int j = 0; j < i - 1; j++) {
				Comparable o1 = (Comparable) a[j];
				Comparable o2 = (Comparable) a[j + 1];
				if (o1.compareTo(o2) == 1) {
					swap(a, j, j + 1);
				}
			}
		}
	}

	private static void swap(Object[] a, int x, int y) {
		Object temp = a[x];
		a[x] = a[y];
		a[y] = temp;
	}

	public static void sort(int[] array) {
		for (int i = array.length - 1; i >= 0; i--) {
			for (int j = 0; j < i; j++) {
				if (array[j] > array[j + 1]) {
					swap(array, j, j + 1);
				}
			}
		}
	}

	private static void swap(int[] array, int x, int y) {
		int temp = array[x];
		array[x] = array[y];
		array[y] = temp;
	}

	public static void pritn(int[] array) {
		for (int i = 0; i < array.length; i++) {
			System.out.println(array[i]);
		}
	}

	public static void pritn(Object[] array) {
		for (int i = 0; i < array.length; i++) {
			System.out.println(array[i].toString());
		}
	}

}
完成Cat的比较,并且任何类只需实现Comparable接口,即可调用DataSorter的sort方法进行排序。

如果以后我们需要对Cat的并不是体重或者身高来比较大小时,我们还是得需要重构Cat类,那么有什么办法可以解决呢?

3. 创建比较器Comparator

我们需要自己去指定一个类的比较规则,并且随时可以更换,这时候比较器就出来了,我们定义一个Comparator接口:

package com.thr.strategy;

public interface Comparator {
	int compare(Object o1, Object o2);
}
然后定义两个比较器,都实现Comparator接口,分别用身高和体重来比较:

package com.thr.strategy;

public class CatHeightComparator implements java.util.Comparator<Cat> {

	@Override
	public int compare(Cat o1, Cat o2) {
		Cat c1 = (Cat) o1;
		Cat c2 = (Cat) o2;
		if (c1.getHeight() > c2.getHeight()) {
			return 1;
		} else if (c1.getHeight() < c2.getHeight()) {
			return -1;
		} else {
			return 0;
		}
	}
}


package com.thr.strategy;

public class CatWeightComparator implements Comparator {

	@Override
	public int compare(Object o1, Object o2) {
		Cat c1 = (Cat) o1;
		Cat c2 = (Cat) o2;
		if (c1.getWeight() > c2.getWeight()) {
			return -1;
		} else if (c1.getHeight() < c2.getHeight()) {
			return 1;
		} else {
			return 0;
		}
	}
}
这是我们修改Cat类,增加成员变量Comparator,设置set和get方法,默认给比较器设成CatHeightComparator,修改Comparable接口实现:

@Override
	public int compareTo(Object o) {
		return comparator.compare(this, o);
	}

这时候,如果需要使用体重来比较大小时,只需要更换比较器就行了。

4. 使用系统的带有泛型的Comparator和Comparable

至此,我们已经自己写好了jdk本来就提供好了的Comparator和Comparable。jdk所提供的Comparator和Comparable还有一个泛型的概念,我们现在使用jdk的这两个接口来实现我们的排序,使用泛型的好处就是不用在程序中强制转换了。修改使用jdk的Comparator和Comparable后运行,没问题。

另外,jdk的Arrays类有一个静态方法,已经帮我们实现了排序的算法,只需要我们传的数组实现了Comparable接口就可以了。

总结一下策略模式:当进行比较大小的时候,定义一个策略的比较器,由具体的比较策略来决定谁大谁小。

源码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: