I walk very slowly, but I never walk backwards
Copy the code
Design Pattern – Template pattern
Become as
Hello, everyone, MY name is Silent. In this lesson, we enter chapter five — the study of behavioral patterns. First of all, the first one is to talk about the template pattern of behavioral patterns
Case demonstration – soybean milk production
The process of making soya-milk material selection –> add ingredients –> soak –> put soya-milk machine to break
Different flavors of soy milk (peanuts, black beans) can be made by adding different ingredients
The steps of selecting ingredients, soaking them and breaking them in a soy milk machine are the same for making soy milk of any flavor
Use template mode to complete
(Because the template pattern is relatively simple and easy to think of, it is directly applied instead of eliciting the template method pattern through the traditional scheme.)
Basic introduction
Template Pattern, also known as Template Method Pattern, his basic introduction is as follows:
Publicly in an abstract class defines a method to perform its template, its subclasses can according to need to rewrite the method implementation, but call will, on the basis of abstract classes defined in short, the template method pattern defines an operation algorithm of the skeleton, and to delay some steps to subclasses, making subclasses can not alter the structure of an algorithm, You can redefine certain steps of the algorithm
For example
In fact, this mode is very common. For example, in actual development, it is often encountered that the code skeleton is similar or even the same, but the specific implementation is different. For example: Process has open, edit, rejected, end, every process includes the steps, the difference is the content of the different process instances they are not the same, again for an example of life, to share a bike is lock, cycling, unlock first, payment, these big steps is fixed, is different for each instance of the specific implementation details. These similar business we can define a class, in one way to execute a process definition, to execute the lock first, for example, to perform cycling, then locked and payments, and the common methods for implementation, such as Shared bike lock and shut method, defined a similar template classes, the specific each subclass, In other words, it is much easier for each shared bike to realize the business logic. In fact, this idea is the template mode
The principle of class diagram
Role analysis
AbstractClass
Abstract classes that implement the template method and define the general flow of the algorithm. Concrete subclasses are required to implement other abstract methods
ConcreteClassA/B
Implement the abstract method in the parent class, complete the relevant steps of the specific subclass in the algorithm
Solution – Template pattern
OK, same idea, let’s first draw a class diagram that uses the template pattern to solve the case requirements, and then implement it in code
The class diagram demo
Code demo
Public abstract class SoyaMilk {//make {final void make(){select(); add(); soak(); beat(); } void select(){system.out.println (" select fresh bean as material "); } // Add (); Void soak(){system.out.println (" soak all the materials for a while "); } // Smash void beat(){system.out.println (" smash all the ingredients in the bean milk machine "); Public class BlackBeanSoyaMilk extends SoyaMilk {@override void add() {system.out.println (" add black SoyaMilk "); } // public class PeanutSoyaMilk extends SoyaMilk {@override void add() {system.out.println (" add peanuts, sugar, etc. "); }} // Client public class Client {public static void main(String[] args) BlackBeanSoyaMilk(); blackBeanSoyaMilk.make(); PeanutSoyaMilk = new peanutSoyaMilk (); // peanutSoyaMilk = new peanutSoyaMilk (); peanutSoyaMilk.make(); }}Copy the code
So, you can write a generic method in an abstract class
Hook method
Next, let’s look at the hook methods in template mode
In the parent class of the template method pattern, we can define a method that does nothing by default, and subclasses can override it as they wish. This method is called a “hook method.”
Case needs
Want to make pure soya-bean milk without adding any ingredients, please use the hook method to modify the previous template method
Code demo
Public abstract class SoyaMilk {//make is a template method that can be made final without subclasses overwriting it. if (needBatching()){ add(); } soak(); beat(); } void select(){system.out.println (" select fresh bean as material "); } // Add (); Void soak(){system.out.println (" soak all the materials for a while "); } // Smash void beat(){system.out.println (" smash all the ingredients in the bean milk machine "); } // Hook method to decide whether to add ingredients Boolean needBatching(){return true; }} public class PureSoyaMilk extends SoyaMilk {@override void add() { } @Override boolean needBatching() { return false; Public class Client {public static void main(String[] args) {pureSoyaMilk = new PureSoyaMilk(); pureSoyaMilk.make(); }}Copy the code
If a subclass overrides a method, it has no implementation by default. If a subclass overrides a method from its parent class, it executes the logic of the subclass. Subclass processing provides a lot of flexibility
Matters needing attention
The basic idea
The algorithm only exists in one place, that is, in the parent class, and it is easy to modify. When you need to modify the algorithm, as long as you modify the template method of the parent class or some steps that have been implemented, the subclass will inherit these changes. The general template methods add the final keyword to prevent the subclass from overwriting the template method
advantage
To maximize code reuse, the parent class’s template methods and some of the implemented steps are inherited and used directly by subclasses.
The template method of the parent class ensures that the structure of the algorithm remains unchanged, while the implementation of some steps is provided by the subclass
disadvantage
Each different implementation requires a subclass implementation, resulting in an increase in the number of classes, making the system larger
Usage scenarios
To complete a process, the process performs a series of steps, the series of steps are essentially the same, but the individual steps may be implemented differently, and the template method pattern is often considered, as illustrated in the example above
IOC source code analysis
Source code analysis
When the Spring IOC container is initialized, the template method pattern is applied, so let’s take a look
We through the ConfigurableApplicationContext as entrance, you can see, it is an interface, this interface defines a lot of ways, one of the important way to refresh (), we came to the realization, The refresh() method is a template method
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // 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) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); }}}Copy the code
This method calls many, many methods, and calls the methods defined in this class.
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
Copy the code
The obtainFreshBeanFactory() method calls two abstract methods, refreshBeanFactory() and getBeanFactory(), which are also defined in this class. It is up to the subclasses to decide which BeanFactory container to choose. Of course, we will focus on the application of the pattern, not the IOC initialization process
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
Copy the code
So you can see, very similar to the make() method in our case, that refresh() defines the general process of running
Are there any hook methods in refresh()? Let’s move on to these two methods
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Initialize other special beans in specific context subclasses.
onRefresh();
Copy the code
As you can see, postProcessBeanFactory() is filled with empty implementations
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
Copy the code
As mentioned earlier, in the template method pattern, some methods are empty implementations, and the main value is to allow subclasses to override them
protected void onRefresh() throws BeansException {
// For subclasses: do nothing by default.
}
Copy the code
Similarly, I called onRefresh() inside the refresh() method, and if the subclass doesn’t override it, it defaults to no implementation, and if the subclass overrides the parent class’s method, then executing the logic of the subclass makes it more flexible to process it, just like in our case making pure soymilk, if you want to make pure soymilk, So subclass rewrite method, to achieve the corresponding pure soybean milk business logic
ConfigurableApplicationContext, of course, more than one implementation class, let’s look at GenericApplicationContext
This class implements refreshBeanFactory() and getBeanFactory() we talked about above
And class AbstractRefreshableApplicationContext, same for refreshBeanFactory (), getBeanFactory () implementation
One could say AbstractRefreshableApplicationContext is an abstract class, it doesn’t matter, below the abstract class and subclass, we are thinking about design patterns, main study it’s a kind of thought, this place is not necessarily the abstract class, also can be an abstract class, It’s a subclass to implement
The process to comb
Sorted out through the above analysis, we come to, first of all, we from the interface ConfigurableApplicationContext inside, this interface declares a template method refresh (), On template method AbstractApplicationContext refresh () implementation, define the general process of running
Method at the same time, it also exists the hook, hook method we mentioned above, if the child does not cover, the default implementation, if a subclass overrides the superclass method, then perform a subclass of logic, the use of hooks methods can let subclasses handle more flexible, AbstractApplicationContext, of course, is an abstract class, So it has concrete subclasses below it, and let’s draw the corresponding class diagram
The class diagram demo
RefreshBeanFactory (), getBeanFactory() is the abstract method postProcessBeanFactory(beanFactory), onRefresh() is the hook method, They are all called in the template method refresh(), and you should understand the application of the template pattern in IOC source code
Next day forecast
OK, this is the end of the template mode. In the next section, we will start the study of command mode. I hope you can stick to it together and really gain something