第二十一章 模板方法(Template Method)

2017-01-13 15:01:04来源:csdn作者:struts2人点击

第七城市
第二十一章 模板方法(Template Method)

什么是模板方法呢?我们先回想以下SQL保存的例子,这个例子要求我们能够同时处理三种类型的SQL语句保存文件:XML格式的文件,Properties格式文件和普通的文本格式的文件。不论那种格式的文件都要求能够提供根据SQL语句名字获得SQL语句的方法。我们可以这样子设计:


public class AbstractSqlManager {


private Map sqlMap ;


public AbstractSqlManager(String filePath) {


sqlMap = initSqlMap(filePath)


}



publicString getSql(String key) {


return (String)sqlMap.get(key);


}



public abstract Map initSqlMap(String filePath);


}



public class XmlSqlManager extends AbstractSqlMamager {


public Map initSqlMap(String filePath) {


// 解析XML文件将SQL语句,以SQL语句的名字为Key,放在sqlMap中。


}


}



public class PropertiesSqlManager extends AbstractSqlMamager {


public Map initSqlMap(String filePath) {


// 解析Properties文件将SQL语句,以SQL语句的名字为Key,放在sqlMap中。


}


}


public class TextSqlManager extends AbstractSqlMamager {


public Map initSqlMap(String filePath) {


// 解析Text文件将SQL语句,以SQL语句的名字为Key,放在sqlMap中。


}


}



参看上述的代码,在AbstractSqlManager中,因为可能处理的文件的内容不同,所以将解析不同代码的方法实现放在了具体的类(XmlSqlManager ,PropertiesSqlManager 和TextSqlManager )中,只在AbstractSqlManager中实现了getSql方法。



我们在来考虑三个具体的实现类,在这些类实现的时候,需要从AbstractSqlManager集成,所以必须实现initSqlMap这个方法,并且必须按照AbstractSqlManager中定义的格式(模板)来实现。



这样可以称initSqlMap为模板方法,也可以称上述的设计为模板方法。



模板方法设计的好处有那些呢?


第一,也是继承的好处,可以重用代码


如上述的例子,使用了模板方法之后,可以将公共的方法和流程在基类中编写,这样可以重用这些代码。(关于继承和组合重用代码的问题参看另外的相关讨论)


第二,可以灵活的对应变更


因为使用了模板方法,所以相同的操作可以在基类中完成,具体的不同实现可以在具体类中完成。所以首先有了变更修改的范围很容易确定,如果是通用的操作则需要在基类中完成,例如initSqlMap之前需要使用日志记录文件的信息。如果是特殊的操作则需要在具体类中完成,例如XML文件格式发生了变更。



第三,规范处理流程(例如有三个模板方法)


使用模板方法可以规范处理流程,例如要对输入的数进行相关的操作,我们可以定义这样的几个过程,(1)数据格式校验(2)数据逻辑校验(3)预处理(4)处理(5)处理输出值(6)结束


我们可以定义这样子一个基类,包含需要的模板方法:


public class BaseTarget{


public void execute(InputVO vo) throw ExecuteException{


try {


formatCheck(vo);


logicCheck(vo);


preProcess(vo);


OutputVO out = process(vo);


formatCheck(out);



} catch(FormatException ex) {


// 异常处理


} catch(LogicException ex) {


// 异常处理


} catch(PreProcessExceptionex) {


// 异常处理


} catch(ProcessExceptionex) {


// 异常处理


} catch(PostProcessExceptionex) {


// 异常处理


}


}



public abstract void formatCheck(InputVO vo) throw FormatException ;



public abstract void logicCheck(InputVO vo) throw LogicException ;



public abstract void preProcess(InputVO vo) throw PreProcessException;



public abstract OutputVO process(InputVO vo) throw ProcessException;



public abstract void postProcess(OutputVO vo) throw PostProcessException;


}



通过上述基类的定义,我们规定了子类型的处理内容(五个需要实现的抽象方法)和处理的顺序(按照execute方法定义的处理顺序执行)。



第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台