首页 > 编程知识 正文

模板模式和策略模式的区别,模板模式和工厂模式区别

时间:2023-05-06 16:52:32 阅读:270953 作者:2325

定义

定义了一个算法的骨架,并允许子类为一个或多个步骤提供实现。模板方式使得子类在不改变算法结构的情况下,重新定义算法的某些步骤。是基于继承的代码复用的基本技术。

简而言之,完成一件事情,有固定的数个步骤,但是会有步骤根据对象的不同,而实现细节不同;就可以在父类中定义一个完成该事情的总方法,按照完成事件需要的步骤去调用其每个步骤的实现方法。固定不变的步骤可以抽取到父类中,需要变化的步骤定义为抽象方法由子类实现。

类型

行为型

适用场景 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现各子类中公共的行为被提取出来并集中到一个公共父类,从而避免代码重复优点 提高复用性(固定不变的方法定义在父类中,由一个固定的顺序调用方法)提高可扩展性(子类根据自己的要求去实现固定顺序中的抽象方法)符合开闭原则缺点 类数目增加增加了系统实现的复杂度继承的缺点,如果父类添加了的新的抽象方法,所有子类都要修改UML类图

抽象(Game)角色的作用:

定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤。定义并实现了一个模板方法。这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。

具体(Cricket)角色的作用:

实现父类所定义的一个或多个抽象方法。每一个具体模板角色可以给出抽象方法的不同实现,从而使得顶级逻辑的实现各不相同。代码Demo

业务场景:以制作一门课程为例,需要先有ppt,再录制视频,然后打包素材,最后写手记;ppt,video,手记都是必须的,但是素材就不一样了,不同课程的素材组成就不同。

UML类图

抽象类AbstractCoursepublic abstract class AbstractCourse { public final void makeCourse() { makePPT(); makeVideo(); if (havaNotes()){ makeNotes(); } doMaterial(); } public final void makePPT(){ System.out.println("制作ppt"); } public final void makeVideo(){ System.out.println("录制视频"); } public boolean havaNotes(){ return true; } public final void makeNotes(){ System.out.println("写手记"); } public abstract void doMaterial();}

makePPT,makeVideo和makeNotes都是模板中固定不变的方法,所以需要加上final以防止子类重写,这里haveNotes是对"钩子"的使用,可以模板的扩展性,makeCourse方法加上final可以有效防止重写所带来步骤顺序的改变。

具体类ConcreteCourse1public class ConcreteCourse1 extends AbstractCourse { @Override public void doMaterial() { System.out.println("图片,视频,PPT,手记"); }} 具体类ConcreteCourse2public class ConcreteCourse extends AbstractCourse { @Override public void doMaterial() { System.out.println("视频,PPT"); } @Override public boolean havaNotes() { return false; }} 源码中的模板方式

HttpService类提供了一个service()方法,这个方法调用七个do方法中的一个或几个,完成对客户端调用的响应。这些do方法需要由HttpServlet的具体子类提供,因此这是典型的模板方法模式。下面是service()方法的源代码:

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 / 1000 * 1000)) { // 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); } }

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。