设计模式之模板方法和策略模式的区别(一)


模板方法:

定义一个算法的大纲,而由其子类定义其中某些步骤的内容。而其算法的个别步骤可以有不同的实现细节。算法结构依然维持不变。用继承的方式改变算法中的具体步骤,依赖程度高,算法在父类(父类是抽象类)中实现,算法的具体步骤在子类中实现。

策略模式:

定义一个算法家族,并让这些算法可以互换。用组合的方式改变整个算法,依赖程度低,父类是接口类,算法在子类中具体实现。

示例冒泡算法:

模板方法有三个类具体代码如下:

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);
}

}

由代码可以看出算法被父类抽象出来了,具体的比如数组的长度、具体数组类型、如何交换、判断是否交换等都在子类里实现。

优质内容筛选与推荐>>
1、软件开发基础汇总
2、给工具栏上的按钮添加文字(VC)
3、iOS 10 之 网络权限带来的坑
4、【译】ASP.NET MVC 5 教程 - 5:使用 SQL 服务器 LocalDB 创建连接字符串
5、常见浏览器的兼容问题


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号