Wang Zheng's Beauty of Design Mode Learning Notes
Principle and implementation of template mode
- Template mode is mainly used to solve the problems of reuse and extension.
- Template mode, full name is template method design mode, English is Template Method Design Patte.
- The template method pattern defines an algorithm skeleton in a method and defers some steps to subclasses. Template method patterns allow subclasses to redefine certain steps in the algorithm without changing the overall structure of the algorithm. Here, the "algorithm" can be interpreted as "business logic" in a broad sense and does not specifically refer to the data structure and the "algorithm" in the algorithm. Here the algorithm skeleton is the "template", and the method that contains the algorithm skeleton is the "template method", which is also the origin of the template method pattern name.
Examples in this article
public abstract class AbstractClass { public final void templateMethod() { //... method1(); //... method2(); //... } protected abstract void method1(); protected abstract void method2(); } public class ConcreteClass1 extends AbstractClass { @Override protected void method1() { //... } @Override protected void method2() { //... } } public class ConcreteClass2 extends AbstractClass { @Override protected void method1() { //... } @Override protected void method2() { //... } } AbstractClass demo = ConcreteClass1(); demo.templateMethod();
- The templateMethod() function is defined as final to prevent subclasses from overriding it.
- method1() and method2() are defined as abstract to force subclasses to implement.
- However, these are not necessary, and in actual project development, the code implementation of template mode is more flexible.
Template mode function one: reuse
- Template mode abstracts a process that does not change in an algorithm into the template method templateMethod() of the parent class, leaving the variable parts method1(), method2() to the subclasses ContreteClass1 and ContreteClass2 for implementation. All subclasses can reuse the process code defined by the template method in the parent class.
1.Java InputStream
public abstract class InputStream implements Closeable { //... Omit other code... public int read(byte b[], int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); } else if (off < 0 || len < 0 || len > b.length - off) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } int c = read(); if (c == -1) { return -1; } b[off] = (byte)c; int i = 1; try { for (; i < len ; i++) { c = read(); if (c == -1) { break; } b[off + i] = (byte)c; } } catch (IOException ee) { } return i; } public abstract int read() throws IOException; } public class ByteArrayInputStream extends InputStream { //... Omit other code... @Override public synchronized int read() { return (pos < count) ? (buf[pos++] & 0xff) : -1; } }
- In code, the read() function is a template method that defines the entire process of reading data and exposes
An abstract method that can be customized by subclasses.
However, this method is also named read(), except that the parameters are different from the template method.
2.Java AbstractList
public boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); boolean modified = false; for (E e : c) { add(index++, e); modified = true; } return modified; } public void add(int index, E element) { throw new UnsupportedOperationException(); }
- The addAll() function can be viewed as a template method, and add() is a method whose subclasses need to be overridden, although it is not declared abstract, the function implementation throws the UnsupportedOperationException exception directly.
Template pattern does two things: expanding
- By extension, we don't mean the extensibility of the code, but the extensibility of the framework, a bit like the inversion of control we mentioned earlier.
1.Java Servlet
- To develop a Web project using a lower-level Servlet, we only need to define a class that inherits the HttpServlet and override the doGet() or doPost() methods in it to process get and post requests, respectively.
- The service() method of HttpServlet is a template method that implements the entire HTTP request execution process, and doGet(), doPost() are the parts of the template that can be customized by subclasses.
- In fact, this is equivalent to the Servlet framework providing an extension point (doGet(), doPost() method that allows framework users to mosaic business code into the framework through extension points without modifying the Servlet framework source code.
2.JUnit TestCase
- When writing unit tests using the JUnit test framework, the test classes we write inherit the TestCase class provided by the framework.
- In the TestCase class, the runBare() function is a template method that defines the overall process for executing test cases: first, perform setUp() to do some preparatory work, then run runTest() to run the real test code, and finally, tearDown() to do the cleaning up.
- Although setUp(), tearDown() are not abstract functions and provide default implementations that do not force subclasses to re-implement, this part can also be customized within subclasses, so it conforms to the definition of template patterns.