模板方法:
定义一个算法的大纲,而由其子类定义其中某些步骤的内容。而其算法的个别步骤可以有不同的实现细节。算法结构依然维持不变。用继承的方式改变算法中的具体步骤,依赖程度高,算法在父类(父类是抽象类)中实现,算法的具体步骤在子类中实现。
策略模式:
定义一个算法家族,并让这些算法可以互换。用组合的方式改变整个算法,依赖程度低,父类是接口类,算法在子类中具体实现。
示例冒泡算法:
模板方法有三个类具体代码如下:
package asdppp.TmBSorter;
//父类为抽象类
public abstract class BubbleSorter
{
private int operations = 0;
//使用protected是为了让子类可以赋值
protected int length = 0;
//封装了抽象的冒泡算法,之所以是抽象的因为在这个算法中swap(怎么交换)、outOfOrder(是否交换)被抽象出来了
protected int doSort()
{
operations = 0;
if (length <= 1)
return operations;
for (int nextToLast = length-2; nextToLast >= 0; nextToLast--)
for (int index = 0; index <= nextToLast; index++)
{
if (outOfOrder(index))
swap(index);
operations++;
}
return operations;
}
//算法中的swap、outOfOrder两个步骤需要子类具体实现对哪些array进行操作
protected abstract void swap(int index);
protected abstract boolean outOfOrder(int index);
}
第一个子类
package asdppp.TmBSorter;
//继承父类也就继承了其算法
public class DoubleBubbleSorter extends BubbleSorter
{
private double[] array = null;
//两个子类使用了父类的算法,两个子类的数据类型参数是swap和outOfOrder虽然代码相同但其实不同
public int sort(double [] theArray)
{
array = theArray;
//对父类算法的length进行赋值
length = array.length;
return doSort();
}
//具体实现了其算法中的具体步骤swap、outOfOrder,其实本例中子类的这两个代码是一样的
protected void swap(int index)
{
double temp = array[index];
array[index] = array[index+1];
array[index+1] = temp;
}
protected boolean outOfOrder(int index)
{
return (array[index] > array[index+1]);
}
}
第二个子类
package asdppp.TmBSorter;
//继承父类也就继承了其算法
public class IntBubbleSorter extends BubbleSorter
{
private int[] array = null;
public int sort(int [] theArray)
{
array = theArray;
length = array.length;
return doSort();
}
//具体实现了其算法中的具体步骤swap、outOfOrder
protected void swap(int index)
{
int temp = array[index];
array[index] = array[index+1];
array[index+1] = temp;
}
protected boolean outOfOrder(int index)
{
return (array[index] > array[index+1]);
}
}
测试类
package asdppp.TmBSorter;
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);
}
public void testEmptyIntArray()
{
int[] array = new int[0];
int operations = (new IntBubbleSorter()).sort(array);
assertEquals(0, operations);
}
public void testIntArrayWithOneElement()
{
int[] array = {0};
int operations = (new IntBubbleSorter()).sort(array);
assertEquals(0, operations);
assertEquals(0, array[0]);
assertEquals(1, array.length);
}
public void testIntArrayWithTwoInOrderElements()
{
int[] array = {0,1};
int operations = (new IntBubbleSorter()).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 = (new IntBubbleSorter()).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 = (new IntBubbleSorter()).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 = (new IntBubbleSorter()).sort(array);
assertEquals("operations", 45, 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 DoubleBubbleSorter()).sort(array);
assertEquals("operations", 45, operations);
for (int i=0; i<10; i++)
assertEquals("array["+i+"]", i, array[i], .001);
}
}
由代码可以看出算法被父类抽象出来了,具体的比如数组的长度、具体数组类型、如何交换、判断是否交换等都在子类里实现。