设计模式之策略模式
策略模式:定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化.
实质:如何让算法和对象分开来,使得算法可以独立于使用它的客户而变化?
我们抛出一个具体的问题来看这个问题:多种方式比较对象的大小?
按照上面说的,我们要将对象和算法分开,所以我定义一个这样的接口(),用于规范一系列的比较类的方法
public interface Comparator { int compare(Object o1, Object o2); }
实现这个接口,写两个比较器。CatHeightcomparator和CatWeightComparator:
package com.bjsxt.dp.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; return 0; } }
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; return 0; } }
就是简单实现了compara方法,根据身高或者体重来比较大小。
看Cat类:
package com.bjsxt.dp.strategy; public class Cat implements java.lang.Comparable<Cat> { private int height; private Comparator comparator = new CatHeightComparator(); //private java.util.Comparator<Cat> comparator = new CatHeightComparator(); public Comparator getComparator() { return comparator; } public void setComparator(Comparator comparator) { this.comparator = comparator; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public Cat(int height, int weight) { super(); this.height = height; this.weight = weight; } public int getWeight() { return weight; } public void setWeight(int weight) { this.weight = weight; } private int weight; @Override public String toString() { return height + "|" + weight; } @Override public int compareTo(Cat o) { return comparator.compare(this, o); } }
定义一个实现Comparable接口的对象,通过set方式注入,然后在comparaTo中去调用注入的对象的compara方法。
定义一个DataSort类:
package com.bjsxt.dp.strategy; import java.lang.Comparable; 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[] a) { for(int i=a.length; i>0; i--) { for(int j=0; j<i-1; j++) { if(a[j] > a[j+1]) { swap(a, j , j+1); } } } } private static void swap(int[] a, int x, int y) { int temp = a[x]; a[x] = a[y]; a[y] = temp; } public static void p(int[] a) { for(int i=0; i<a.length; i++) { System.out.print(a[i] + " "); } System.out.println(); } public static void p(Object[] a) { for(int i=0; i<a.length; i++) { System.out.print(a[i] + " "); } System.out.println(); } }
//一个测试方法
public class Test { public static void main(String[] args) { //int[] a = {9, 5, 3, 7, 1}; Cat[] a = {new Cat(5, 5), new Cat(3, 3), new Cat(1, 1)}; //Dog[] a = {new Dog(5), new Dog(3), new Dog(1)}; DataSorter.sort(a); //java.util.Arrays.sort(a); DataSorter.p(a); } }
今天比较累,不太想去解释这些问题。
说说核心理解吧!
策略模式的核心问题就是将算法和对象分开,实现可扩展!对象具体使用的东西,定义成策略类,通过注入的方式注入到对象,对象内部调用注入类的具体实现的方法,实现对象中策略可以轻松替换。
其实在jdk中也就是这样干的,我上面部分注释掉的内容,就是jdk的实现!