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

推荐订阅源

罗磊的独立博客
Cisco Talos Blog
Cisco Talos Blog
C
Check Point Blog
博客园_首页
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Martin Fowler
Martin Fowler
Recorded Future
Recorded Future
S
Security @ Cisco Blogs
L
LINUX DO - 最新话题
博客园 - 司徒正美
P
Privacy International News Feed
G
Google Developers Blog
I
Intezer
Hacker News - Newest:
Hacker News - Newest: "LLM"
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
C
Cybersecurity and Infrastructure Security Agency CISA
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Scott Helme
Scott Helme
K
Kaspersky official blog
I
InfoQ
Y
Y Combinator Blog
T
The Blog of Author Tim Ferriss
Webroot Blog
Webroot Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
大猫的无限游戏
大猫的无限游戏
D
Docker
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
W
WeLiveSecurity
Microsoft Azure Blog
Microsoft Azure Blog
Spread Privacy
Spread Privacy
量子位
H
Hacker News: Front Page
Simon Willison's Weblog
Simon Willison's Weblog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
SecWiki News
SecWiki News
S
Security Affairs
Latest news
Latest news
人人都是产品经理
人人都是产品经理
C
CERT Recently Published Vulnerability Notes
S
Security Archives - TechRepublic
V
Visual Studio Blog
T
Troy Hunt's Blog
S
Secure Thoughts
F
Fortinet All Blogs
V
V2EX
The Register - Security
The Register - Security
J
Java Code Geeks
MongoDB | Blog
MongoDB | Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO

博客园 - 夜雨竹林

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