Basic concepts
What is a template method: The parent class defines the skeleton (which methods and order are called), and some specific methods are implemented by subclasses.
The biggest benefit: code reuse, reduced duplication of code. In addition to the specific methods that subclasses want to implement, the other methods and method invocation order are pre-written in the parent class.
So there are two types of methods in the parent template method:
1, common method: All subclasses will use the code
2, different methods: sub-class to cover the method, divided into two kinds:
A, abstract method: The parent class is an abstract method, the subclass must overwrite
B, Hook method: The parent class is an empty method, the subclass inherits the default is also empty
Note: Why is called a hook, the subclass can pass this hook (method), control the parent class, because this hook is actually the method of the parent class (empty method)!
Template method pattern, similar to the real template, a document template is usually a finished part of the table (table template is like a template method), everyone will get a copy of the table (Specific implementation Class) to fill in some items, everyone can be specified items (abstract method or Hook method) to fill, The required fields in the table are like the abstract methods that must be implemented, and the non-mandatory fields in the table are the hook methods. Of course, the analogy is not exactly the same as the reality.
UML diagram
Java Code Show
The following code shows how the template method pattern is typically in Java code:
1, first define an interface, mainly defines the template method
Public Interface Templateinterface { publicvoid execute ();}
2, the abstract class implements the interface, mainly realizes the template method logic, the template method calls own logic method, but also has the most important hook method and the abstract method
Public Abstract classTemplateabstractclassImplementstemplateinterface{/**Template Method*/@Override Public voidExecute () {predosomething (); Abstractmethod (); Hookmethod (); Afterdosomething (); } Private voidpredosomething () {System.out.println ("Before do some thing in abstract class"); } Private voidafterdosomething () {System.out.println ("After doing some thing in abstract class"); } /**Abstract Methods*/ Public Abstract voidAbstractmethod (); /**Hook Method*/ Public voidHookmethod () {}}
3, two sub-classes, one only implemented an abstract method, two implemented an abstract method and covered the hook method
Public class extends templateabstractclass{ /** Abstract method */ @Override publicvoid Abstractmethod () { System.out.println ("Does another thing by Subclassone" ); }}
Public classSubclasstwoextendstemplateabstractclass{/**Abstract Methods*/@Override Public voidAbstractmethod () {System.out.println ("Do another thing by Subclasstwo"); } /**Hook Method*/@Override Public voidHookmethod () {System.out.println ("Hook method in Subclasstwo"); }}
Template method Patterns in spring
Almost all of the extensions in spring use the template method pattern, which should be a lot of jdbctemplate, but have not learned there yet, here is the IOC part of the template method mode!
Note: Seemingly in the business system is rarely seen, is the developer's coding ability problem or the actual situation does not apply, but in the framework of many, Java IO, Spring, hibernate, etc., may be as a framework to consider more is the extension of the problem!
The following code shows the template method pattern used when the spring IOC container is initialized. (Intercept some key code)
1, first define an interface Configurableapplicationcontext, declare template method refresh
Public Interface extends ApplicationContext, Lifecycle, closeable { /** declares a template method */void Throws beansexception, illegalstateexception;}
2, abstract class Abstractapplicationcontext implementation of the interface, the main implementation of the Template method refresh (this method is very important, is a variety of IOC container initialization of the portal) logic
Public Abstract classAbstractapplicationcontextextendsDefaultresourceloaderImplementsConfigurableapplicationcontext, Disposablebean {/**concrete implementation of template method*/ Public voidRefresh ()throwsbeansexception, illegalstateexception {synchronized( This. Startupshutdownmonitor) { //Prepare this context for refreshing.Preparerefresh (); //Note that this method is called with two abstract methods Refreshbeanfactory, Getbeanfactory//Tell the subclass to refresh the internal bean factory.Configurablelistablebeanfactory beanfactory =obtainfreshbeanfactory (); //Prepare The Bean Factory for use with this context.preparebeanfactory (beanfactory); Try{//Note that this method is the hook method//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 (); //Note that this method is the hook method//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. Throwex; } } }
Here there is an abstract method Obtainfreshbeanfactory, two hook methods Postprocessbeanfactory and Onrefresh, to see their definition in the class
Two hook methods:
protected void postprocessbeanfactory (configurablelistablebeanfactory beanfactory) { } protected voidthrows beansexception { // for Subclasses:do No by default. }
Then look at the abstract method of getting the spring container:
/**in fact, he only called two abstract methods inside of him **/ protectedconfigurablelistablebeanfactory obtainfreshbeanfactory () {refreshbeanfactory (); Configurablelistablebeanfactory beanfactory=getbeanfactory (); if(logger.isdebugenabled ()) {Logger.debug ("Bean Factory for" + getdisplayname () + ":" +beanfactory); } returnbeanfactory; }protected Abstract voidRefreshbeanfactory ()throwsbeansexception, IllegalStateException; Public AbstractConfigurablelistablebeanfactory Getbeanfactory ()throwsIllegalStateException;
Specific to take that kind of beanfactory container decision right to the sub-class!
3, the implementation of the sub-class, the implementation of the abstract method Getbeanfactory sub-categories are:
Abstractrefreshableapplicationcontext:
Public Abstract classAbstractrefreshableapplicationcontextextendsAbstractapplicationcontext {@Override Public Finalconfigurablelistablebeanfactory getbeanfactory () {synchronized( This. Beanfactorymonitor) { if( This. Beanfactory = =NULL) { Throw NewIllegalStateException ("Beanfactory not initialized or already closed –" + "call ' Refresh ' before a Ccessing beans via the ApplicationContext "); } //Here's this.beanfactory in another abstract method refreshbeanfactory the settings of the return This. beanfactory; } }}
Public class extends Implements beandefinitionregistry { @Override publicfinal Configurablelistablebeanfactory getbeanfactory () { /// The same this.beanfactory here is set in another abstract method returnthis. beanfactory;} }
In fact, the difference is not very large, we can look at another abstract method Refreshbeanfactory implementation, two abstract methods of the use of the combination.
So the UML here is:
Design Patterns--spring Template method patterns used in IOC