In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article shares with you the content of sample analysis of template method patterns in Java design patterns. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.
Template method mode
In program development, we often encounter this situation: the algorithm to be implemented by a method requires multiple steps, but some of the steps are fixed, while others are not fixed. In order to improve the extensibility and maintainability of the code, the template method pattern comes in handy in this scenario.
For example, the steps of making an online course can be simplified to four steps:
1. Make PPT
two。 Record video
3. Write notes
4. Provide course materials
Among them, the actions of 1, 2 and 3 are fixed in all courses, step 3 is optional, and step 4 is different in each course (some courses need to provide source code, some need to provide picture files, etc.)
We can determine the sequence of the entire process in the parent class and implement the fixed steps, leaving the unfixed steps to the subclass implementation. You can even use a hook method to let subclasses decide whether a method in the process is executed or not.
Introduction
Template method pattern: define a framework for the algorithm in operation and defer some steps to subclasses. The template method pattern allows subclasses to redefine certain steps of an algorithm without changing the structure of the algorithm. Template method pattern is a kind of code reuse technology based on inheritance, which is a kind of behavior pattern.
Role
AbstractClass (abstract class): a series of basic operations (PrimitiveOperations) are defined in an abstract class, which can be concrete or abstract. Each basic operation corresponds to a step of the algorithm, and these steps can be redefined or implemented in its subclasses. At the same time, a template method (Template Method) is implemented in the abstract class, which is used to define an algorithm framework. The template method can call not only the basic methods implemented in the abstract class, but also the basic methods implemented in the subclasses of the abstract class, as well as methods in other objects.
ConcreteClass (concrete subclass): it is a subclass of an abstract class that implements abstract basic operations declared in the parent class to complete the steps of a subclass-specific algorithm, or overrides concrete basic operations that have been implemented in the parent class.
A template method is a method defined in an abstract class that combines basic operating methods to form a total algorithm or a total behavior. This template method is defined in the abstract class and is fully inherited by the subclass without modification. Template method is a concrete method, which gives a top-level logical framework, and the composition steps of logic can be concrete methods or abstract methods in abstract classes.
The basic method is the method to realize each step of the algorithm, which is a part of the template method. Basic methods can be divided into three types: abstract method (Abstract Method), concrete method (Concrete Method) and hook method (Hook Method).
Abstract method: an abstract method is declared by an abstract class and implemented by its concrete subclass.
Specific method: a concrete method is declared and implemented by an abstract class or concrete class, and its subclasses can be overridden or directly inherited.
Hook method: you can "hook" with some specific steps to implement different steps in the template method under different conditions
Code demonstration
So we fix the whole process in the abstract class through the template method pattern, in which the implementation of 1, 2, 3 is completed in the abstract class, the execution of 3 is controlled by the hook method, and 4 is implemented by the subclass.
Abstract classes are defined as follows:
/ / Abstract course class public abstract class Course {protected final void makeCourse () {this.makePPT (); this.makeVideo (); if (needWriteArticle ()) {this.writeArticle ();} this.packageCourse ();} / / final means that the parent class cannot be modified after the subclass inherits and the method final void makePPT () {System.out.println ("1. Make PPT ");} final void makeVideo () {System.out.println (" 2. Make a video ");} final void writeArticle () {System.out.println (" 3. Write course notes ");} / / hook method protected boolean needWriteArticle () {return false;} / / Abstract method, leaving subclasses to implement abstract void packageCourse ();}
The makeCourse method is a template method, which defines the basic flow of making a network course. The three steps of makePPT, makeVideo and writeArticle are fixed in all courses, so they are modified with the final keyword; the packageCourse method may be different in all courses, so it is declared as an abstract method and implemented by the subclass itself; the hook method needWriteArticle returns a value of type boolean to control whether or not to write course notes
Subclass JavaCourse, which implements the abstract method packageCourse and overrides the hook method needWriteArticle
Public class JavaCourse extends Course {@ Override void packageCourse () {System.out.println ("4. Provide Java course source code");} @ Override protected boolean needWriteArticle () {return true;}}
The subclass FECourse, which implements the abstract method packageCourse and rewrites the hook method needWriteArticle, in which the result of the hook method is given to the client to determine
Public class JavaCourse extends Course {@ Override void packageCourse () {System.out.println ("4. Provide Java course source code");} @ Override protected boolean needWriteArticle () {return true;}}
Client test
Public class TEST {public static void main (String [] args) {System.out.println ("Java course start---"); Course javaCourse = new JavaCourse (); javaCourse.makeCourse (); System.out.println ("Java course end---\ n"); System.out.println ("Front-end course start---") Course feCourse = new FECourse (false); feCourse.makeCourse (); System.out.println ("front-end course end---");}}
Output result
Java course start
1. Make PPT
two。 Make a video
3. Write notes
4. Provide Java course source code
Java course end
Front-end course start
1. Make PPT
two。 Make a video
4.1 provide front-end code for the course
4.2 provide multimedia materials such as pictures of the course
Front-end course end
Summary of advantages of template method pattern
An algorithm is formally defined in the parent class, and the processing of the details is realized by its subclass. when the subclass implements the detailed processing algorithm, it does not change the execution order of the steps in the algorithm.
Template method pattern is a kind of code reuse technology, which is particularly important in the design of class library. it extracts the common behavior in the class library, puts the common behavior in the parent class, and implements different behaviors through its subclasses. it encourages us to properly use inheritance to achieve code reuse.
You can implement a reverse control structure in which the subclass overrides the hook method of the parent class to determine whether a particular step needs to be performed.
In the template method mode, the basic methods of the parent class can be overridden by subclasses. Different subclasses can provide different implementations of the basic methods. It is convenient to replace and add new subclasses, which conforms to the principle of single responsibility and the principle of opening and closing.
Shortcoming
It is necessary to provide a subclass for the different implementation of each basic method. If there are too many variable basic methods in the parent class, the number of classes will increase, the system will be larger, and the design will be more abstract. At this time, the bridge pattern can be combined to design.
Applicable scenario
Some complex algorithms are segmented, and the fixed part of the algorithm is designed as template method and parent class specific method, and some details that can be changed are implemented by its subclass. That is, the invariant part of an algorithm is implemented at once, and the variable behavior is left to the subclass to implement.
Common behaviors in each subclass should be extracted and grouped into a common parent class to avoid code duplication.
It is necessary to use the subclass to determine whether a step in the parent algorithm is executed or not, so as to realize the reverse control of the subclass to the parent class.
General template methods add the final keyword to prevent subclasses from overriding the method
Typical Application of template method pattern for Source Code Analysis template method pattern in Servlet
Servlet (Server Applet) is the abbreviation of Java Servlet. The main function of server-side program written in Java is to browse and modify data interactively and generate dynamic Web content. In every Servlet, we must implement the Servlet interface. GenericServlet is a general-purpose Servlet that is not specific to any protocol. It implements the Servlet interface, while HttpServlet inherits from GenericServlet, implements the Servlet interface, and provides a general implementation for the Servlet interface to deal with the HTTP protocol, so the Servlet we define only needs to inherit HttpServlet.
The brief code for HttpServlet is as follows
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); } } // ...省略...} 在 HttpServlet 的 service 方法中,首先获得到请求的方法名,然后根据方法名调用对应的 doXXX 方法,比如说请求方法为GET,那么就去调用 doGet 方法;请求方法为POST,那么就去调用 doPost 方法 HttpServlet 相当于定义了一套处理 HTTP 请求的模板;service 方法为模板方法,定义了处理HTTP请求的基本流程;doXXX 等方法为基本方法,根据请求方法做相应的处理,子类可重写这些方法;HttpServletRequest 中的Method则起到钩子方法的作用. 在开发javaWeb应用时,自定义的Servlet类一般都扩展 HttpServlet 类,譬如我们实现一个输出 Hello World! 的 Servlet 如下 // 扩展 HttpServlet 类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("Hello World!"); } public void destroy() { // ... }} 该自定义的 Servlet 重写了 doGet 方法,当客户端发起 GET 请求时将得到 Hello World!Spring中的IOC容器启动-refresh()方法 Spring IOC容器初始化时运用到的模板方法模式 1、首先定义一个接口ConfigurableApplicationContext,声明模板方法refresh public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable { /**声明了一个模板方法*/ void refresh() throws BeansException, IllegalStateException;} 2、抽象类AbstractApplicationContext实现了接口,主要实现了模板方法refresh(这个方法很重要,是各种IOC容器初始化的入口)的逻辑 public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean { /**模板方法的具体实现*/ public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); //注意这个方法是,里面调用了两个抽象方法refreshBeanFactory、getBeanFactory // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { //注意这个方法是钩子方法 // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); //注意这个方法是钩子方法 // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } } } 这里最主要有一个抽象方法obtainFreshBeanFactory、两个钩子方法postProcessBeanFactory和onRefresh,看看他们在类中的定义 两个钩子方法: protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { } protected void onRefresh() throws BeansException { // For subclasses: do nothing by default. } 再看看获取Spring容器的抽象方法: /**其实他内部只调用了两个抽象方法**/ protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; } protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException; public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException; 具体要取那种BeanFactory容器的决定权交给了子类! 3、具体实现的子类,实现了抽象方法getBeanFactory的子类有: AbstractRefreshableApplicationContext public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext { @Override public final ConfigurableListableBeanFactory getBeanFactory() { synchronized (this.beanFactoryMonitor) { if (this.beanFactory == null) { throw new IllegalStateException("BeanFactory not initialized or already closed - " + "call 'refresh' before accessing beans via the ApplicationContext"); } //这里的this.beanFactory在另一个抽象方法refreshBeanFactory的设置的 return this.beanFactory; } }} public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry { @Override public final ConfigurableListableBeanFactory getBeanFactory() { //同样这里的this.beanFactory在另一个抽象方法中设置 return this.beanFactory; }} 其实这里的差别还不是很大,我们可以看看另一个抽象方法refreshBeanFactory的实现,两个抽象方法的配合使用。Thank you for reading! This is the end of this article on "sample analysis of template method patterns in Java design patterns". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, you can share it for more people to see!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.