惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LangChain Blog
V
V2EX
爱范儿
爱范儿
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Martin Fowler
Martin Fowler
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Apple Machine Learning Research
Apple Machine Learning Research
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
罗磊的独立博客
小众软件
小众软件
Vercel News
Vercel News
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
V
Visual Studio Blog
J
Java Code Geeks
P
Proofpoint News Feed
MongoDB | Blog
MongoDB | Blog
B
Blog
美团技术团队
量子位

博客园 - 夜雨竹林

asp mvc3资料 设计模式之命令模式 面向对象的分析和设计遵循的原则 设计模式之模板方法和策略模式的区别(一) 系统分析师网上内容推荐 英语学习资料 Repository模式 战略性设计之上下文 moq英文官方资料 moq中文介绍 领域驱动设计软件核心复杂性应对之道速查 UML用例图中包含(include)、扩展(extend)和泛化(generalization)三种 领域驱动设计软件核心复杂性应对之道 研究 asp.net mvc2 ajax 原理 studyurl aspdotnet部分资源 Asp.net MVC权限设计思考 asp.net小技巧 标准的ASP.NET名称空间
设计模式之模板方法和策略模式的区别(二)
夜雨竹林 · 2011-07-24 · via 博客园 - 夜雨竹林

策略类包括如下五个类:

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