天天看點

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

繼續閱讀