天天看点

Strategy Pattern-比较算法的封装(Comaparable&Comparator接口)

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。

Strategy Pattern-比较算法的封装(Comaparable&Comparator接口)

意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

如何解决:将这些算法封装成一个一个的类,任意地替换。

关键代码:实现同一个接口。

使用场景: 1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。 2、一个系统需要动态地在几种算法中选择一种。 3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。

Strategy Pattern-比较算法的封装(Comaparable&Comparator接口)
Strategy Pattern-比较算法的封装(Comaparable&Comparator接口)

Test测试类

package com.dp.Strategy.test;

import com.dp.Strategy.Comparable.Cat;
import com.dp.Strategy.Comparable.Dog;
import com.dp.Strategy.Comparator.CatHeightComparator;
import com.dp.Strategy.Comparator.CatWeightComparator;
import com.dp.Strategy.util.DataSorter;
/**
 * 策略模式-比较算法的封装(Comaparable&Comparator接口):
 * 
 * 策略模式允许在程序执行时选择不同的算法.比如在排序时,传入不同的比较器(Comparator),就采用不同的算法.
 * 
 * 将待比较的类实现java.lang.Comparable接口并重写其中的comparaTo()方法,
 * comparaTo()方法中
 * 使用实现了java.util.Comparator接口的特定比较器的compara()方法,
 * 不同的比较器实现了对不同的比较规则算法的封装
 * 最后使用java.util.Arrays.sort(Object o)对对象进行排序
 */
public class Test {
	public static void main(String[] args) {
		//Dog和Cat继承的是自己写的Comparable接口,使用的比较器也是继承的自己写的Comparator接口
		Dog[] d = {new Dog(1),new Dog(6),new Dog(5)};
		DataSorter.sort(d);
		DataSorter.p(d);
		
		Cat[] c1 = {new Cat(1,1,new CatHeightComparator()),
				new Cat(5,5,new CatHeightComparator()),new Cat(4,4,new CatHeightComparator())};
		DataSorter.sort(c1);
		/*java.util.Arrays.sort(c);   
		 *jdk中的排序方法,使用这个方法需要继承java.lang.Comparable接口
		 * !继承这里我自己写的Comparable接口会抛出异常!
		 * */
		DataSorter.p(c1);
		
		Cat[] c2= {new Cat(1,1,new CatWeightComparator()),
				new Cat(5,5,new CatWeightComparator()),new Cat(4,4,new CatWeightComparator())};
		DataSorter.sort(c2);
		DataSorter.p(c2);
		
/*
Dog [food=1] Dog [food=5] Dog [food=6] 
Cat [height=1, weight=1] Cat [height=4, weight=4] Cat [height=5, weight=5] 
Cat [height=5, weight=5] Cat [height=4, weight=4] Cat [height=1, weight=1] 	
 */
	}
}
           

Comparable接口

package com.dp.Strategy.Comparable;
/**
 * 此接口和jdk中的一致
 * 继承此接口要重写comparaTo()方法,缺点是只能按照一种规则排序
 */
public interface Comparable<T> {//
	int compareTo(T o);//interface里的方法默认public
}
           

Cat类

package com.dp.Strategy.Comparable;

import com.dp.Strategy.Comparator.CatHeightComparator;
import com.dp.Strategy.Comparator.Comparator;

public class Cat implements Comparable<Cat>{  //使用的泛型,继承接口时要指定类型
	
	private int height;
	private int weight;
	//由接口组合(强聚合)
	private Comparator<Cat> comparator;
	
	public Cat(int height, int weight,Comparator<Cat> comparator) {
		super();
		this.height = height;
		this.weight = weight;
		this.comparator=comparator;
	}

	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 "Cat [height=" + height + ", weight=" + weight + "]";
	}

	@Override
	public int compareTo(Cat c) {//指定类型
		return comparator.compare(this, c);
	}
	
}
           

Dog类

package com.dp.Strategy.Comparable;

import com.dp.Strategy.Comparator.Comparator;
import com.dp.Strategy.Comparator.DogFoodComparator;

public class Dog implements Comparable<Dog>{//要想比较大小就要实现Comparable接口并重写compareTo()方法
	
	private int food;
	private Comparator<Dog> comparator = new DogFoodComparator();
	
	public Dog(int food) {
		super();
		this.food = food;
	}

	public int getFood() {
		return food;
	}

	public void setFood(int food) {
		this.food = food;
	}
	
	@Override
	public String toString() {
		return "Dog [food=" + food + "]";
	}

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

Comparator接口

package com.dp.Strategy.Comparator;
/**
 *此接口和jdk中的一致
 *可以定义不同的比较器,分别按不同的规则重写compara()方法
 */
public interface Comparator<T> {
	int compare(T o1,T o2);  //jdk中使用的是泛型,继承此接口时要指定类型
}
 
           

CatHeightComparator 按照猫的高度比较

package com.dp.Strategy.Comparator;

import com.dp.Strategy.Comparable.Cat;
/**
 * 按照猫的高度比较大小
 */
public class CatHeightComparator implements Comparator<Cat>{

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

}
           

CatWeightComparator 按照猫的重量比较

package com.dp.Strategy.Comparator;

import com.dp.Strategy.Comparable.Cat;
/**
 * 按照猫的重量比较大小
 */
public class CatWeightComparator implements Comparator<Cat>{

	@Override
	public int compare(Cat c1, Cat c2) {
		if(c1.getWeight()>c2.getWeight()) return -1;//重量重的小,以便区分排序结果
		else if(c1.getWeight()<c2.getWeight()) return 1;
		return 0;
	}

}
           

DogFoodComparator 按照狗的食量比较

package com.dp.Strategy.Comparator;

import com.dp.Strategy.Comparable.Dog;
/**
 * 按照狗的食量比较大小
 */
public class DogFoodComparator implements Comparator<Dog> {

	@Override
	public int compare(Dog d1, Dog d2) {
		if(d1.getFood() > d2.getFood()) {
			return 1;
		}else if(d1.getFood() > d2.getFood()) {
			return -1;
		}else return 0;
	}

}
           

DataSorter排序工具

package com.dp.Strategy.util;

import com.dp.Strategy.Comparable.Comparable;

public class DataSorter {

	public static void sort(Object[] a) {//冒择路(入)兮(希尔)快归堆       可以使用直接传入Comparable
        for(int i=a.length ; i>0 ; i--) {
        	for(int j=0 ; j<i-1 ; j++) {
        		Comparable c1 = (Comparable)a[j];  //强制类型转换
        		Comparable c2 = (Comparable)a[j+1];
        		if(c1.compareTo(c2) == 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 p(Object[] a) {
		for(int i=0 ; i<a.length ;i++) {
			System.out.print(a[i]+" ");  //调用a[i]的ToString()方法,因此该方法要重写
		}
		System.out.println();
	}

}
           

策略模式-菜鸟教程

http://www.runoob.com/design-pattern/strategy-pattern.html

继续阅读