夜雨竹林
落叶无声

策略类包括如下五个类:

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、从本例中也能看出多用组合、少用继承的原则的好处和策略模式比模板方法更符合多用组合、少用继承的原则。

posted on 2011-07-24 22:23  夜雨竹林  阅读(1956)  评论(0编辑  收藏  举报