一. 模式概述
摸板方法(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:
定义接口 =》 定义接口实现的抽象方法 =》 定义具体业务逻辑
调用入口:
<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()); }
。。
相关推荐
5. Template 模式:Template 模式在 Tomcat 中主要应用于模板引擎,例如在 Server.xml 文件中,我们可以看到许多 Template 的实现,例如 JasperTemplateEngine 等,这些 Template 负责生成动态页面。 设计模式分析...
模板方法设计模式是一种行为设计模式,它...模板方法设计模式是设计模式中的基础模式之一,理解并正确使用它可以提高软件的灵活性、可维护性和扩展性。在实际开发中,我们应该根据需求灵活运用,以达到最佳的设计效果。
《Java设计模式之禅》是一本深入浅出讲解设计模式的书籍,书中不仅包含23种经典设计模式的案例,还详细介绍了设计模式背后的思想和原则,适合初学者以及对设计模式有一定了解的程序员阅读。本书旨在帮助读者理解如何...
模板方法模式是设计模式中的一种行为模式,它在软件工程中扮演着重要的角色,尤其是在C++这样的面向对象编程语言中。这种模式定义了一个操作中的算法骨架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的...
模板方法模式(Template Method)是设计模式中行为型模式的一种,它定义了操作中的算法骨架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。这个模式在C++编程中有着...
模板设计模式是面向对象设计模式的一种,它在软件工程中扮演着重要的角色,尤其是在构建可扩展和可维护的代码库时。这个模式属于行为设计模式,主要用来在父类中定义一个操作流程的骨架,而将具体实现细节留给子类去...
模板模式是一种行为设计模式,它使你能在不破坏封装性的前提下,定义对象间的一系列基本操作,并在子类中实现这些操作的具体步骤。在模板模式中,一个抽象类公开定义了执行它的方法的方式,而将具体实现延迟到子类中...
**模板模式(Template Pattern)**是一种行为设计模式,它使你能在抽象类中定义操作算法的框架,而将一些步骤延迟到子类中。这样,子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 在Java、C#等面向...
模板方法模式是设计模式中行为模式的一种,它在软件开发中起到了重要的作用,尤其是在复杂的系统设计中。模板方法模式遵循“开闭原则”,允许我们定义一个算法的骨架,同时允许子类在不改变整体结构的情况下,对算法...
13. 模板方法模式(Template Method):定义一个操作中的算法骨架,而将一些步骤延迟到子类中,实现了基类的算法可复用。 行为型设计模式 14. 观察者模式(Observer Pattern):定义对象之间的一种一对多的依赖...
如策略模式(Strategy)、模板方法模式(Template Method)、观察者模式(Observer)、命令模式(Command)、迭代器模式(Iterator)、访问者模式(Visitor)、备忘录模式(Memento)、状态模式(State)、职责链...
### 设计模式之模板方法模式解析 #### 一、引言 在软件开发过程中,我们经常面临这样的场景:有一些步骤是固定的,而某些步骤则可能因具体实现而异。为了解决这类问题,设计模式中引入了一种叫做“模板方法模式”的...
模板方法模式是设计模式中行为型模式的一种,它在软件工程中扮演着非常重要的角色,尤其是在Java编程中。模板方法模式定义了一个操作中的算法骨架,而将一些步骤延迟到子类中。它允许子类不改变一个算法的结构即可重...
《设计模式:可复用面向对象软件的基础》一书介绍了23种经典的设计模式,这些模式大致可以分为三大类: 1. **创建型模式**:专注于对象的创建机制,确保系统在合适的时机创建正确的对象。 - **单例模式**...
在这个“设计模式之美”的学习笔记中,我们将探讨一些主要的设计模式,以及它们在实际开发中的应用。 首先,我们从创建型模式开始。这类模式主要用于对象的创建,如单例模式(Singleton)、工厂模式(Factory ...
设计模式是在软件工程领域内,针对常见问题的一套经过验证的解决方案,它们为解决特定类型的问题提供了模板,帮助开发者设计出更灵活、可维护、易于扩展的代码结构。 ### 创建型模式 #### Factory模式 Factory模式...
模板方法模式是软件设计模式中的一种行为模式,它在面向对象设计中扮演着重要的角色,尤其是在代码复用和保持代码结构整洁方面。该模式定义了一个操作中的算法骨架,而将一些步骤延迟到子类中。使得子类可以不改变一...
- 模板方法模式(Template Method):定义一个操作中的算法骨架,而将一些步骤延迟到子类中。 - 访问者模式(Visitor):为一个对象结构定义一个作用在其上的操作。 这些设计模式的彩图和截图可能是为了直观地...
"GOF之23种设计模式"是由四名作者——Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides(通常称为Gang of Four,简称GOF)在他们的著作《设计模式:可复用面向对象软件的基础》中提出的。这些模式为创建可...
《设计模式:可复用面向对象软件的基础》是一本由Erich Gamma、Richard Helm等四位国际知名的软件工程师共同编写的经典之作,该书提供了面向对象软件设计中常用的模式,并通过具体的案例解释了这些模式如何帮助解决...