Strategy将通用算法抽象为一个接口,算法用户和提供算法实现的类构成组合关系;Template Method将算法定义为一个抽象方法,让具体子类实现该抽象方法,它体现的是一种继承关系。Strategy比Template Method更灵活,适用于需要动态改变算法的情况。
各位可以看这个二个模式的类图,可以发现template pattern其实是违反dip原则的,如果算法的过程本省不稳定,本人不推荐使用该模式。
但是我需要指出的是template模式很强大,template pattern是我使用最为频繁的模式之一。
public abstract class TestCase {
protected final void setup() {
DebugLog.log("test case has setup");
}
abstract void run();
public void execute() {
setup();
run();
teardown();
}
protected final void teardown() {
DebugLog.log("test case has tear down");
}
}
public class TestCaseImp1 extends TestCase {
@Override
void run() {
DebugLog.log("TestCaseImp1 test case is running");
}
}
public class TestCaseImp2 extends TestCase {
@Override
void run() {
DebugLog.log("TestCaseImp2 test case is running");
}
}
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
TestCase[] testcases=new TestCase[]{new TestCaseImp1(),new TestCaseImp2()};
int size = testcases.length;
for(int start=0;start<size;start++)
{
TestCase testcase=testcases[start];
testcase.execute();
}
}
}
可以看出testcase中都从startup 以teardown作为终结就是因为使用了template模式
再看看stategy模式:
public interface SortHandle
{
void Swap(int index);
Boolean OutOfOrder(int index);
int Length();
void SetArray(Object array);
}
public class IntSortHandle implements SortHandle {
private int[] array = null;
@Override
public void Swap(int index) {
int t = array[index];
array[index] = array[index + 1];
array[index + 1] = t;
}
@Override
public Boolean OutOfOrder(int index) {
return (array[index] > array[index + 1]);
}
@Override
public int Length() {
return array.length;
}
@Override
public void SetArray(Object array) {
this.array = (int[])array;
}
public void PrintArray()
{
int size = array.length;
for(int start=0;start<size;start++)
{
DebugLog.log(Double.toString(array[start]));
}
}
}
public class BubbleSorter
{
private int operations = 0;
protected int length = 0;
private SortHandle sorthandle = null;
public BubbleSorter(SortHandle sh)
{
sorthandle = sh;
}
public int Sort(Object array)
{
sorthandle.SetArray(array);
length = sorthandle.Length();
operations = 0;
if (length < 1)
return operations;
for (int nextToLast = length - 1; nextToLast >= 0; nextToLast--)
{
for (int index = 0; index < nextToLast; index++)
{
if (sorthandle.OutOfOrder(index))
sorthandle.Swap(index);
operations++;
}
}
return operations;
}
}
public class StringSortHandle implements SortHandle {
private String[] array = null;
@Override
public void Swap(int index) {
String t = array[index];
array[index] = array[index + 1];
array[index + 1] = t;
}
@Override
public Boolean OutOfOrder(int index) {
return (array[index].compareToIgnoreCase(array[index + 1])<=0?true:false);
}
@Override
public int Length() {
return array.length;
}
@Override
public void SetArray(Object array) {
this.array = (String[])array;
}
public void PrintArray()
{
int size = array.length;
for(int start=0;start<size;start++)
{
DebugLog.log((array[start]));
}
}
}
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
IntSortHandle intHandler = new IntSortHandle ();
BubbleSorter bubbleIntHandler = new BubbleSorter(intHandler);
bubbleIntHandler.Sort(new int[] { 8, 2, 3, 1, 5 });
intHandler.PrintArray();
StringSortHandle stringHandler = new StringSortHandle ();
BubbleSorter bubbleStrSorter = new BubbleSorter(stringHandler);
bubbleStrSorter.Sort(new String[] { "ssad", "adsd", "vvvv", "23123", "asdasdas"});
stringHandler.PrintArray();
}
}
再用template模式实现相同的功能:
public abstract class BubbleSorter
{
private int operations = 0;
protected int length = 0;
protected int DoSort()
{
operations = 0;
if (length < 1)
return operations;
for (int nextToLast = length - 1; nextToLast >= 0; nextToLast--)
{
for (int index = 0; index < nextToLast; index++)
{
if (OutOfOrder(index))
Swap(index);
operations++;
}
}
return operations;
}
protected abstract void Swap(int index);
protected abstract Boolean OutOfOrder(int index);
}
public class DoubleBubblerSorter extends BubbleSorter
{
private double[] array = null;
public int Sort(double[] a)
{
array = a;
length = a.length;
return DoSort();
}
@Override
protected java.lang.Boolean OutOfOrder(int index) {
return (array[index] > array[index + 1]);
}
@Override
protected void Swap(int index) {
double t = array[index];
array[index] = array[index + 1];
array[index + 1] = t;
}
public void PrintArray()
{
int size = array.length;
for(int start=0;start<size;start++)
{
DebugLog.log(Double.toString(array[start]));
}
}
}
public class StringBubblerSorter extends BubbleSorter
{
private String[] strings = null;
public int Sort(String[] a)
{
strings = a;
length = a.length;
return DoSort();
}
@Override
protected java.lang.Boolean OutOfOrder(int index) {
return (strings[index].compareTo(strings[index + 1])<=0?true:false);
}
@Override
protected void Swap(int index) {
String t = strings[index];
strings[index] = strings[index + 1];
strings[index + 1] = t;
}
public void PrintArray()
{
int size = strings.length;
for(int start=0;start<size;start++)
{
DebugLog.log(strings[start]);
}
}
}
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
DoubleBubblerSorter bs = new DoubleBubblerSorter();
bs.Sort(new double[] { 1, 2.2, 3, 4, 2.1, 3.5, 3.8, 4.5, 1.6 });
bs.PrintArray();
System.out.println("======================================");
StringBubblerSorter ss = new StringBubblerSorter();
ss.Sort(new String[] { "23","assas","3sadasd","sddsd"});
ss.PrintArray();
}
}
通过比较二者都及比较优雅的冒泡算法问题,一个通过继承,一个通过委托。
委托更加灵活,继承代码效率更高。