GOF设计模式之TEMPLATE METHOD(模板方法)

来源:互联网 发布:手机淘宝收货地址 编辑:程序博客网 时间:2024/06/05 11:37

概述

本文将和读者一起来理解GOF设计模式之TEMPLATE METHOD(模板方法)。同样,本文将用JAVA对GOF中的示例代码改些,同时附上测试用例。

模式结构

GOF对TEMPLATE METHOD(模板方法)的模式结构描述如
这里写图片描述
模板模式在于将实现的流程封装在基类中,将实现的内容封装到子类中,从而键流程和内容解耦。模式结构中,AbstractClass.TemplateMethod()封装了流程,它将在恰当的时机调用PrimitiveOperation1和PrimitiveOperation2。而后两者将在ConcreteClass中具体实现。好处在于将子类公有的流程逻辑抽象到了基类中,减少了代码的重复同时去除了流程和内容上的耦合。在各类框架下工作的程序猿们,我相信对这个模式的接触不比单例模式少。

代码示例

示例代码的类结构如
这里写图片描述
很简单,一个基类View用display方法控制了展示视图的流程逻辑。子类在doDisplay,autoFocus,和resetFocus方法中进行具体实现。
示例代码如

package gof.view;public abstract class View {    public void setFocus() {        System.out.println("execute set focus");    }    public void resetFocus() {        System.out.println("execute reset focus");    }    public abstract void doDisplay();    public void display() {        this.setFocus();        this.doDisplay();        this.resetFocus();    }}
package gof.view;public class MyView extends View{    @Override    public void doDisplay() {        System.out.println("display in MyView");    }}

测试用例

package gof.view;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class ViewConfig {      @Bean      public View view() {        return new MyView();      }}
package gof.view;import static org.junit.Assert.assertEquals;import org.junit.Rule;import org.junit.Test;import org.junit.contrib.java.lang.system.StandardOutputStreamLog;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import org.springframework.test.context.support.AnnotationConfigContextLoader;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes=ViewConfig.class,loader=AnnotationConfigContextLoader.class)public class ViewTest {    @Autowired    View view;    protected String newLineMark;    @Autowired    public void setNewLineMark() {        this.newLineMark = System.getProperty("line.separator");    }    @Rule()    public final StandardOutputStreamLog log = new StandardOutputStreamLog();    @Test    public void view() {        this.view.display();        assertEquals("execute set focus" + this.newLineMark        + "display in MyView" + this.newLineMark        + "execute reset focus" + this.newLineMark, this.log.getLog());    }}
0 0