一. 模式概述
摸板方法(Template Method)模式是一种非常简单而又经常使用的设计模式.先创建一个父类,把其中的一个或多个方法留给子类去实现 ,这实际上就是在使用摸板模式.所谓的 摸板模式可以这样来理解:"在一个类中定义一个算法,但将此算法的某些细节留到子类中去实现.换句话说,基类是一个抽象类,那么你就是在使用一种简单形式 的摸板模式."
更近一步可以这样来理解:"准备一个抽象类,将部分逻辑以具体方法的形式实现,然后申明一些抽象方法来 迫使 子类实现剩余的逻辑.不同的子类可以以不同的方法实现这些抽象方法,从而对剩余的逻辑有不同的实现."
二. 模式意图
将一个类的基本部分抽取出来放到一个基类中,这样它就不必重复出现在几个派生类里.
三. 模式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:
定义接口 =》 定义接口实现的抽象方法 =》 定义具体业务逻辑
调用入口:
<bean id="proxy" class="com.project.proxy.impl.comm.ProxyCreatorImpl"/> <bean id="route" class="com.project.proxy.impl.rest.RestCreatorImpl"/>
@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<ProxyCreatorStep> 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接口,将创建代理服务拆分如下步骤:<br> * 1、初始化构建环境<br> * 2、创建客户端<br> * 3、创建服务端<br> * 4、打包<br> * 5、部署<br> * 实现时,如果忽略某一步骤,在实现时返回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<ProxyCreatorStep> steps = new ArrayList<ProxyCreatorStep>(); /** * 使用无参构造默认代理生成状态为成功 */ public ProxyCreatorProgram() { this.status = Constants.SUCCESS; } ... }
ProxyCreatorProgram pro = ...; //获取整个操作中的所有步骤的LOG信息 List<ProxyCreatorStep> steps = pro.getSteps(); StringBuilder sb = new StringBuilder(); for(ProxyCreatorStep stp : steps){ sb.append(stp.getDetail()); }
。。