策略类包括如下五个类:
package asdppp.StBSorter;
public interface SortHandle
{
//组合的方式包含算法,这里算法指的就是outOfOrder、swap、setArray、length
public void swap(int index);
public boolean outOfOrder(int index);
public int length();
public void setArray(Object array);
}
package asdppp.StBSorter;
public class DoubleBubbleSorter implements SortHandle
{
private double[] array = null;
public void swap(int index)
{
double temp = array[index];
array[index] = array[index+1];
array[index+1] = temp;
}
public int length()
{
return array.length;
}
public void setArray(Object array)
{
this.array = (double[])array;
}
public boolean outOfOrder(int index)
{
return (array[index] > array[index+1]);
}
}
package asdppp.StBSorter;
public class IntSortHandle implements SortHandle
{
private int[] array = null;
public void swap(int index)
{
int temp = array[index];
array[index] = array[index+1];
array[index+1] = temp;
}
public void setArray(Object array)
{
this.array = (int[])array;
}
public int length()
{
return array.length;
}
public boolean outOfOrder(int index)
{
return (array[index] > array[index+1]);
}
}
package asdppp.StBSorter;
public class BubbleSorter
{
private int operations = 0;
private int length = 0;
//组合的方式包含算法,这里算法指的就是outOfOrder、swap、setArray、length
private SortHandle itsSortHandle = null;
public BubbleSorter(SortHandle handle)
{
itsSortHandle = handle;
}
public int sort(Object array)
{
itsSortHandle.setArray(array);
length = itsSortHandle.length();
operations = 0;
if (length <= 1)
return operations;
for (int nextToLast = length-2; nextToLast >= 0; nextToLast--)
for (int index = 0; index <= nextToLast; index++)
{
if (itsSortHandle.outOfOrder(index))
itsSortHandle.swap(index);
operations++;
}
return operations;
}
}
package asdppp.StBSorter;
public class QuickBubbleSorter
{
private int operations = 0;
private int length = 0;
private SortHandle itsSortHandle = null;
public QuickBubbleSorter(SortHandle handle)
{
itsSortHandle = handle;
}
public int sort(Object array)
{
itsSortHandle.setArray(array);
length = itsSortHandle.length();
operations = 0;
if (length <= 1)
return operations;
boolean thisPassInOrder = false;
for (int nextToLast = length-2; nextToLast >= 0 && !thisPassInOrder; nextToLast--)
{
thisPassInOrder = true; //Potentially.
for (int index = 0; index <= nextToLast; index++)
{
if (itsSortHandle.outOfOrder(index))
{
itsSortHandle.swap(index);
thisPassInOrder = false;
}
operations++;
}
}
return operations;
}
}
测试类如下:
package asdppp.StBSorter;
import junit.framework.TestCase;
public class TestBubbleSort extends TestCase
{
public static void main(String[] args)
{
junit.swingui.TestRunner.main(args);
}
public TestBubbleSort(String name)
{
super(name);
}
private QuickBubbleSorter sorter = null;
protected void setUp()
{
sorter = new QuickBubbleSorter(new IntSortHandle());
}
public void testEmptyIntArray()
{
int[] array = new int[0];
int operations = sorter.sort(array);
assertEquals(0, operations);
}
public void testIntArrayWithOneElement()
{
int[] array = {0};
int operations = sorter.sort(array);
assertEquals(0, operations);
assertEquals(0, array[0]);
assertEquals(1, array.length);
}
public void testIntArrayWithTwoInOrderElements()
{
int[] array = {0,1};
int operations = sorter.sort(array);
assertEquals("operations",1, operations);
assertEquals(0, array[0]);
assertEquals(1, array[1]);
assertEquals(2, array.length);
}
public void testIntArrayWithTwoOutOfOrderElements()
{
int[] array = {1,0};
int operations = sorter.sort(array);
assertEquals("operations",1, operations);
assertEquals("array[0]", 0, array[0]);
assertEquals("array[1]", 1, array[1]);
assertEquals(2, array.length);
}
public void testIntArrayWithThreeOutOfOrderElements()
{
int[] array = {3,2,1};
int operations = sorter.sort(array);
assertEquals("operations", 3, operations);
assertEquals("array[0]", 1, array[0]);
assertEquals("array[1]", 2, array[1]);
assertEquals("array[2]", 3, array[2]);
assertEquals(3, array.length);
}
public void testIntArrayWithTenOutOfOrderElements()
{
int[] array = {9,8,7,6,5,4,3,2,1,0};
int operations = sorter.sort(array);
assertEquals("operations", 45, operations);
for (int i=0; i<10; i++)
assertEquals("array["+i+"]", i, array[i]);
}
public void testIntArrayWithTenInOrderElements()
{
int[] array = {0,1,2,3,4,5,6,7,8,9};
int operations = sorter.sort(array);
assertEquals("operations", 9, operations);
for (int i=0; i<10; i++)
assertEquals("array["+i+"]", i, array[i]);
}
public void testIntArrayWithTenOddOrderElements()
{
int[] array = {0,1,2,3,4,5,6,7,9,8};
int operations = sorter.sort(array);
assertEquals("operations", 17, operations);
for (int i=0; i<10; i++)
assertEquals("array["+i+"]", i, array[i]);
}
public void testDoubleArrayWithTenOutOfOrderElements()
{
double[] array = {9,8,7,6,5,4,3,2,1,0};
int operations = (new BubbleSorter(new DoubleBubbleSorter())).sort(array);
assertEquals("operations", 45, operations);
for (int i=0; i<10; i++)
assertEquals("array["+i+"]", i, array[i], .001);
}
}
对以上同一问题的两个设计模式的实现进行分析有以下几点:
1、本例中模板方法和策略模式设计的目的都是遵循oo的原则封装变化,本例中所谓的变化就是数据类型的变化(int和double等)。
2、策略模式也可以用来实现模板方法的设计目的,因为它把每个步骤的实现作为封装的算法。
3、在本例Template Method的子类IntBubbleSorter直接依赖(继承)于抽象类BubbleSorter,BubbleSorter包含着冒泡排序算法。可以看出子类中swap和outOfOrder的实现依赖了BubbleSorter包含的冒泡排序算法,在子类中的函数sort看出。对于DIP(依赖倒置原则)没有很好遵守。再看本例中的策略模式例子包含算法的BubbleSorter依赖接口SortHandle,子类实现接口(也依赖接口)不依赖BubbleSorter更符合DIP(依赖倒置原则)。
4、从本例中也能看出多用组合、少用继承的原则的好处和策略模式比模板方法更符合多用组合、少用继承的原则。