三、应用
模版设计模式,应用非常广泛,比如javaEE中的servlet,当我们每创建一个servlet的时候,都会继承HttpServlet
,其实HttpServlet
已经为我们提供一套操作流程,我们只需要重写里面的方法即可!
HttpServlet 的部分源码如下:
public abstract class HttpServlet extends GenericServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // ... } protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // ... } protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // ... } protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // ... } protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // ... } protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // ... } protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // ... } protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getMethod(); if (method.equals(METHOD_GET)) { long lastModified = getLastModified(req); if (lastModified == -1) { // servlet doesn't support if-modified-since, no reason // to go through further expensive logic doGet(req, resp); } else { long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE); if (ifModifiedSince < lastModified) { // If the servlet mod time is later, call doGet() // Round down to the nearest second for a proper compare // A ifModifiedSince of -1 will always be less maybeSetLastModified(resp, lastModified); doGet(req, resp); } else { resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED); } } } else if (method.equals(METHOD_HEAD)) { long lastModified = getLastModified(req); maybeSetLastModified(resp, lastModified); doHead(req, resp); } else if (method.equals(METHOD_POST)) { doPost(req, resp); } else if (method.equals(METHOD_PUT)) { doPut(req, resp); } else if (method.equals(METHOD_DELETE)) { doDelete(req, resp); } else if (method.equals(METHOD_OPTIONS)) { doOptions(req,resp); } else if (method.equals(METHOD_TRACE)) { doTrace(req,resp); } else { // // Note that this means NO servlet supports whatever // method was requested, anywhere on this server. // String errMsg = lStrings.getString("http.method_not_implemented"); Object[] errArgs = new Object[1]; errArgs[0] = method; errMsg = MessageFormat.format(errMsg, errArgs); resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg); } } // ...省略... }
自定义一个 HelloWorld 的 Servlet 类,如下:
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloWorld extends HttpServlet { public void init() throws ServletException { // ... } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<h1>Hello World!</h1>"); } public void destroy() { // ... } }
四、总结
模版模式有着许多的优点:
1、模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码;2、子类实现算法的某些细节,有助于算法的扩展;3、通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合开放-封闭原则
;
也有些缺点:1、每个不同的实现都需要定义一个子类,这会导致类的个数的增加,设计更加抽象
如果某些类有一些共同的行为,可以使用模版设计模式,创建一个抽象类,将共同的行为定义在抽象类中,可以有效的减少子类重复的代码。