一. 模式概述
摸板方法(Template Method)模式是一种非常简单而又经常使用的设计模式.先创建一个父类,把其中的一个或多个方法留给子类去实现 ,这实际上就是在使用摸板模式.所谓的 摸板模式可以这样来理解:"在一个类中定义一个算法,但将此算法的某些细节留到子类中去实现.换句话说,基类是一个抽象类,那么你就是在使用一种简单形式 的摸板模式."
更近一步可以这样来理解:"准备一个抽象类,将部分逻辑以具体方法的形式实现,然后申明一些抽象方法来 迫使 子类实现剩余的逻辑.不同的子类可以以不同的方法实现这些抽象方法,从而对剩余的逻辑有不同的实现."
定义一个操作中算法的骨架,将一些步骤的执行延迟到其子类中.
使用Java的抽象类时,就经常会使用到Template模式,因此Template模式使用很普遍.而且很容易理解和使用。
二. 模式意图
将一个类的基本部分抽取出来放到一个基类中,这样它就不必重复出现在几个派生类里.
三. 模式UML图
抽象摸板角色:
1. 定义了一个或多个抽象操作,以便让子类实现.
2. 定义并实现了一个摸板方法.
具体摸板角色:
1. 实现父类所定义的一个或多个抽象方法.
2. 每一个抽象摸板角色都可以有任意多个具体摸板角色与之对应.
3. 每一个具体摸板角色都可以给出这些抽象方法的不同实现.
public abstract class Template
{
protected abstract void checkFinance();
public final void doTotal()
//模板方法
{
checkFinance();
System.out.println("Company Finance has been check-out ");
}
}
public class FilialeTemplate extends Template
{
protected void checkFinance()
{
System.out.println("Filiale render check report");
}
}
public class TestTemplate
{
public static void main(String[] args)
{
Template template = new FilialeTemplate();
template.doTotal();
}
}
来源:http://flysnail.iteye.com/blog/185559
参考:http://www.jdon.com/designpatterns/template.htm
例子2:
定义接口 =》 定义接口实现的抽象方法 =》 定义具体业务逻辑
调用入口:
@Resource(name = "proxy")
private ProxyCreator proxyCreator;
@Resource(name = "rest")
private ProxyCreator restCreator;
ProxyCreatorProgram pro = null;
if(Constants.ESB_SRV_TYPE_RESTFUL.equals(tmp.getServiceType())){
pro = restCreator.createProxy(tmp.getWsdlUrl().trim(), serverType, serverHome, proxyBuildPath, tmp.getServiceNameEn().trim(), tmp.getProviderAppCode().trim(), null);
}else{
pro = proxyCreator.createProxy(tmp.getWsdlUrl().trim(), serverType, serverHome, proxyBuildPath, tmp.getServiceNameEn().trim(), tmp.getProviderAppCode().trim(), null);
}
//获取整个操作中的所有步骤的LOG信息
List steps = pro.getSteps();
StringBuilder sb = new StringBuilder();
for(ProxyCreatorStep stp : steps){
sb.append(stp.getDetail());
}
具体实现:
/**
* 提供生成代理服务的一些方法
*
*/
public interface ProxyCreator {
ProxyCreatorProgram createProxy(String uri, ServerType serverType, String serverHome, String proxyBuildPath, String serviceName, String modelName, String serviceVersion, String... additional );
ProxyCreatorProgram createProxy(WebServiceProject project);
boolean deleteProxy(ServerType serverType, String serverHome, String proxyBuildPath, String serviceName, String modelName, String serviceVersion);
}
/**
* 实现了ProxyCreator接口,将创建代理服务拆分如下步骤:
* 1、初始化构建环境
* 2、创建客户端
* 3、创建服务端
* 4、打包
* 5、部署
* 实现时,如果忽略某一步骤,在实现时返回null
*
*/
public abstract class AbstractProxyCreator implements ProxyCreator {
@Override
public ProxyCreatorProgram createProxy(String uri, ServerType serverType, String serverHome, String proxyBuildPath, String serviceName, String modelName, String serviceVersion, String... additional) {
WebServiceProject project = new WebServiceProject(uri, serverType, serverHome, proxyBuildPath, serviceName, modelName, serviceVersion);
if(additional.length > 0){
project.setCallbackUrl(additional[0]);
}
return createProxy(project);
}
@Override
public ProxyCreatorProgram createProxy(WebServiceProject project) {
ProxyCreatorProgram log = new ProxyCreatorProgram();
// 请在实现的抽象方法中捕获异常,在返回值中说明执行成功/失败
// 初始化构建环境
ProxyCreatorStep buildLog = initBuildEnv(project);
if(buildLog != null){
log.getSteps().add(buildLog);
if(!Constants.SUCCESS.equals(buildLog.getStatus())){
log.setStatus(Constants.FAILURE);
return log;
}
}
// 创建客户端
ProxyCreatorStep clientLog = createClient(project);
if(clientLog != null){
log.getSteps().add(clientLog);
if(!Constants.SUCCESS.equals(clientLog.getStatus())){
log.setStatus(Constants.FAILURE);
return log;
}
}
// 创建服务端
ProxyCreatorStep serverLog = createServer(project);
if(serverLog != null){
log.getSteps().add(serverLog);
if(!Constants.SUCCESS.equals(serverLog.getStatus())){
log.setStatus(Constants.FAILURE);
return log;
}
}
// 打包代理服务
ProxyCreatorStep pkgLog = pkg(project);
if(pkgLog != null){
log.getSteps().add(pkgLog);
if(!Constants.SUCCESS.equals(pkgLog.getStatus())){
log.setStatus(Constants.FAILURE);
return log;
}
}
// 部署代理服务
ProxyCreatorStep deployLog = deploy(project);
if(deployLog != null){
log.getSteps().add(deployLog);
if(!Constants.SUCCESS.equals(deployLog.getStatus())){
log.setStatus(Constants.FAILURE);
return log;
}
}
log.setWsdl(generateWsdl(project));
return log;
}
/**
*
* 生成wsdl地址
*
* @param project
* @return
*/
protected abstract String generateWsdl(WebServiceProject project);
/**
*
* 创建构建环境
*
* @param project
*
* @return
* 请在实现的抽象方法中捕获异常,在返回值中说明执行成功/失败
*
*/
protected abstract ProxyCreatorStep initBuildEnv(WebServiceProject project);
/**
*
* 创建客户端
*
* @param project
*
* @return
* 请在实现的抽象方法中捕获异常,在返回值中说明执行成功/失败
*
*/
protected abstract ProxyCreatorStep createClient(WebServiceProject project);
/**
*
* 创建服务端
*
* @param project
*
* @return
* 请在实现的抽象方法中捕获异常,在返回值中说明执行成功/失败
*
*/
protected abstract ProxyCreatorStep createServer(WebServiceProject project);
/**
*
* 打包代理服务
*
* @param project
*
* @return
* 请在实现的抽象方法中捕获异常,在返回值中说明执行成功/失败
*
*/
protected abstract ProxyCreatorStep pkg(WebServiceProject project);
/**
*
* 部署代理服务
*
* @param project
*
* @return
* 请在实现的抽象方法中捕获异常,在返回值中说明执行成功/失败
*
*/
protected abstract ProxyCreatorStep deploy(WebServiceProject project);
}
具体业务逻辑类(有多种不同的具体实现类,只展示一个):
/**
* 本类是使用J2EE实现服务代理:
* 客户端由wsimport生成,服务端通过ejb发布成webservice
*
*/
public class ProxyCreatorImpl extends AbstractProxyCreator {
private static final Logger logger = LoggerFactory.getLogger(ProxyCreatorImpl.class);
private EnvCreator ec = new EnvCreator();
private ClientCreator cc = new ClientCreator();
private ServerCreator sc = new ServerCreator2();
@Override
protected ProxyCreatorStep initBuildEnv(WebServiceProject project) {
ProxyCreatorStep log = null;
try {
log = ec.createAntEnv(project);
} catch (Exception e) {
e.printStackTrace();
// 处理文件处理中的运行时异常
log = new ProxyCreatorStep();
log.setName("initBuildEnv");
log.setOrder(1);
log.setStatus(Constants.FAILURE);
log.setDetail(ExceptionUtils.getStackTrace(e));
}
return log;
}
@Override
protected ProxyCreatorStep createClient(WebServiceProject project) {
ProxyCreatorStep log = null;
try {
log = cc.wsimport(project.getWebServiceInfo().getSourceUrl(), project.getSrcLocation(), project.getBasePkg());
} catch (Exception e) {
e.printStackTrace();
// 处理异常
log = new ProxyCreatorStep();
log.setName("createClient");
log.setOrder(2);
log.setStatus(Constants.FAILURE);
log.setDetail(ExceptionUtils.getStackTrace(e));
}
return log;
}
@Override
protected ProxyCreatorStep createServer(WebServiceProject project) {
ProxyCreatorStep log = null;
try {
log = sc.createEjbWs(project);
} catch (Exception e) {
e.printStackTrace();
// 处理异常
log = new ProxyCreatorStep();
log.setName("createServer");
log.setOrder(3);
log.setStatus(Constants.FAILURE);
log.setDetail(ExceptionUtils.getStackTrace(e));
}
return log;
}
@Override
protected ProxyCreatorStep pkg(WebServiceProject project) {
ProxyCreatorStep log = new ProxyCreatorStep();
log.setName("pkg");
log.setOrder(4);
log.setStatus(Constants.SUCCESS);
StringBuilder detail = new StringBuilder();
// 获取打包命令
detail.append("\u25c6\u83b7\u53d6\u6253\u5305\u547d\u4ee4").append("\n");
String[] cmd = AntExecutor.generateCmd(project.getLocation() + File.separator + "build.xml", "jar", null);
logger.debug(" cmd : " + Arrays.toString(cmd));
detail.append(Arrays.toString(cmd)).append("\n");
try {
detail.append(AntExecutor.execute(cmd).replaceAll("\n", "\n "));
log.setDetail(detail.toString());
} catch (Exception e) {
e.printStackTrace();
// 处理异常
log.setStatus(Constants.FAILURE);
log.setDetail(e.getMessage());
}
return log;
}
@Override
protected ProxyCreatorStep deploy(WebServiceProject project) {
ProxyCreatorStep log = new ProxyCreatorStep();
log.setName("deploy");
log.setOrder(5);
log.setStatus(Constants.SUCCESS);
StringBuilder detail = new StringBuilder();
// 获取部署命令
detail.append("\u25c6\u83b7\u53d6\u90e8\u7f72\u547d\u4ee4").append("\n");
String[] cmd = AntExecutor.generateCmd(project.getLocation() + File.separator + "build.xml", "deploy", null);
logger.debug(" cmd : " + Arrays.toString(cmd));
detail.append(Arrays.toString(cmd)).append("\n");
try {
detail.append(AntExecutor.execute(cmd).replaceAll("\n", "\n "));
log.setDetail(detail.toString());
} catch (Exception e) {
e.printStackTrace();
// 处理异常
log.setStatus(Constants.FAILURE);
log.setDetail(e.getMessage());
}
return log;
}
@Override
public boolean deleteProxy(ServerType serverType, String serverHome,
String proxyBuildPath, String serviceName, String modelName,
String serviceVersion) {
WebServiceProject project = new WebServiceProject("", serverType, serverHome, proxyBuildPath, serviceName, modelName, serviceVersion);
try {
AntExecutor.execute(AntExecutor.generateCmd(project.getLocation() + File.separator + "build.xml", "undeploy", null));
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
@Override
protected String generateWsdl(WebServiceProject project) {
StringBuilder wsdl = new StringBuilder();
if(ServerType.JBoss.equals(project.getTargetServerType())){
wsdl.append("/").append(project.getName()).append("/").append(project.getName()).append("?wsdl");
}
return wsdl.toString();
}
/**/
public static void main(String[] args) {
String uri = "http://10.204.104.157:8888/ESB_YS_YS_InquiryEventsReferralsInfoSrv/ESBYSYSInquiryEventsReferralsInfoSrv?wsdl";
ServerType serverType = ServerType.JBoss;
String serviceName = "SB_IM_MDM_ImportAdminOrgSrv";
String modelName = "IM_MDM";
//String serviceVersion = "v1.0";
String serviceVersion = null;
String proxyBuildPath = "D:/Work/test/SRVSRC";
String serverHome = "D:/Work/servers/jboss-5.1.0.GA";
ProxyCreatorImpl pci = new ProxyCreatorImpl();
ProxyCreatorProgram pcp = pci.createProxy(uri, serverType, serverHome, proxyBuildPath, serviceName, modelName, serviceVersion);
System.out.println(pcp.toString());
pci.deleteProxy(serverType, serverHome, proxyBuildPath, serviceName, modelName, serviceVersion);
}
}
细节点:
捕获异常明细:
import java.io.PrintWriter;
import java.io.StringWriter;
//跟控制台的异常信息一样
public class ExceptionUtils {
public static String getStackTrace(Throwable t) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
try {
t.printStackTrace(pw);
return sw.toString();
} finally {
pw.close();
}
}
}
ProxyCreatorStep 获取每一步的执行状态和detail log信息
ProxyCreatorProgram
整个流程的POJO,包括多个子流程对象ProxyCreatorStep
/**
* 创建步骤日志类
*
*/
public class ProxyCreatorStep {
private String status;
private String name;
private String detail;
private int order;
public ProxyCreatorStep() {
this.status = Constants.SUCCESS;
}
...
}
/**
* 描述创建代理服务流程
*
*/
public class ProxyCreatorProgram {
private String status;
private String wsdl;
/**
* 服务流程队列
*/
private List steps = new ArrayList();
/**
* 使用无参构造默认代理生成状态为成功
*/
public ProxyCreatorProgram() {
this.status = Constants.SUCCESS;
}
...
}
ProxyCreatorProgram pro = ...;
//获取整个操作中的所有步骤的LOG信息
List steps = pro.getSteps();
StringBuilder sb = new StringBuilder();
for(ProxyCreatorStep stp : steps){
sb.append(stp.getDetail());
}
。。