论坛首页 编程语言技术论坛

设计模式(八)——模板方法模式

浏览 2488 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-07-17  

设计模式(八)——模板方法模式


这几天杂七杂八的事有点多,停了几日,今日继续,今天讲最简单的模板方法,但是却是用的比较广泛的。首先来明确下概念吧,模板方法的写法是这样,准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现,这就是模板方法模式的用意。模板方法模式需要开发抽象类和具体子类的设计师之间的协作。一个设计师负责给出一个算法的轮廓和骨架,另一些设计师则负责给出这个算法的各个逻辑步骤。代表这些具体逻辑步骤的方法称做基本方法(primitive method);而将这些基本方法汇总起来的方法叫做模板方法(template method),这个设计模式的名字就是从此而来。

具体来看代码吧,大家比较熟悉的单元测试junit的源码在设计上就应用了模板方法模式,下面我来模拟一下,记住,只是模拟一个大概的流程,表达一个思路,实际上真正的junit的源码要复杂一点。

首先我们知道,单元测试一般有三个流程,即数据初始化阶段,实际测试阶段,数据回收阶段,我们设计时会把这些方法都写成抽象的,因为我们并不知道你要测什么,你需要什么资源,得由具体测试的人去实现这些方法。

package com.gy.designpattern.template;
/**
 * ClassName:MyTestCase <br/>
 * Function: 自定义一个测试的模板. <br/>
 * Reason:	 TODO ADD REASON. <br/>
 * Date:     2012-7-17 下午4:14:20 <br/>
 * @author   gongyong
 * @version
 * @since    JDK 1.6
 * @see
 */
public abstract class MyTestCase {
	 //定义抽象操作,以便让子类实现
    protected void setUp() throws Exception {
    }

    protected void runTest() throws Throwable {
    }

    protected void tearDown() throws Exception {
    }

    //具体的模板方法,定义出逻辑骨架
    public void runBare() throws Throwable {
	    setUp();
	    runTest();
	    tearDown();
    }
}

 下面,我们假如要测试一个获取消息的方法,那我们会这么写这个测试

package com.gy.designpattern.template;
/**
 * ClassName:MessageTest <br/>
 * Function: 抽象模板的继承,这里实现具体的基本方法. <br/>
 * Reason:	 TODO ADD REASON. <br/>
 * Date:     2012-7-17 下午4:16:36 <br/>
 * @author   gongyong
 * @version
 * @since    JDK 1.6
 * @see
 */
public class MessageTest extends MyTestCase{
	/**
	 * 第一步,初始化.
	 * @see com.gy.designpattern.template.MyTestCase#setUp()
	 */
	public void setUp() throws Exception {
		System.out.println("测试前的数据初始化工作");
    }

    /**
     * 第二步,具体的测试.
     * @see com.gy.designpattern.template.MyTestCase#runTest()
     */
    protected void runTest() throws Throwable {
    	 System.out.println("这里对被测方法进行测试。。。");
    }

    /**
     *第三步,测试完毕,资源回收.
     * @see com.gy.designpattern.template.MyTestCase#tearDown()
     */
    public void tearDown() throws Exception {
        System.out.println("测试完或对资源的释放操作");
    }
}

 具体的测试我就不写了,我就用一句话代替了,这个应该懂的。到这里其实就已经写完了。当然,你还可以写其他任何的测试,只不过是都继承自这个抽象类,然后具体实现这三个方法而已。这就是模板方法的用处。最后我们运行这个单元测试,模拟个运行器:

package com.gy.designpattern.template;
/**
 * ClassName:Client <br/>
 * Function: 模拟一个单元测试的运行器. <br/>
 * Reason:	 TODO ADD REASON. <br/>
 * Date:     2012-7-17 下午4:25:37 <br/>
 * @author   gongyong
 * @version
 * @since    JDK 1.6
 * @see
 */
public class Client {
	public static void main(String[] args) throws Throwable{
		MessageTest messageTest=new MessageTest();
		messageTest.runBare();
	}
}

 实际上,我们看junit的源码,它不是这么直接的,但是他就是按照这个思路设计的,它只不过还拐了几个弯而已,比如我们在继承类里实现了一个 protected void runTest()方法,实际上我们在写的时候就不是这么写的,名字我们可以随便起(3.X以前的名字必须带test),然后junit用适配器模式将这个方法配成了 runTest方法,其实还是一样。

好吧,就说到这里。

 

论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics