java design pattern -- template method

Template method Template

The design of the overall algorithm is an abstract class, which has a series of abstract methods, representing the steps in the algorithm that can be customized, and this class contains some general code. Each variant of the algorithm is implemented by concrete classes that override abstract methods to provide corresponding implementations.

The Template Method pattern removes duplication of code in subclasses by moving constant behavior to the superclass. The subclass implements some details of the algorithm, which is helpful for the extension of the algorithm. Calling operations implemented by a subclass through a parent class, and adding new behaviors through subclass extension, conforms to the "open-closed principle".

Example:

Suppose there is an inspection process to check identity information, credit information, and income. These sources of information are different, such as checking the information of companies and individuals, then for different sources of information, the checking methods are different, but the checking process is unified, such as defining a process (or priority) Check identity information --> credit information --> Income situation. 

Code:

public class TemplateTest{

    /**
     * Check the template used
     */
    static abstract class CheckTemplate {
        //check identity information
        protected abstract void identity();
        //check credit information
        protected abstract void creditHistory();
        //check income information
        protected abstract void incomeHistory();

        //check process definition
        public void check(){
            this.identity();
            this.creditHistory();
            this.incomeHistory();
        }
    }

    /**
     * Base class for checking patterns, providing default implementations
     */
    static class CheckTemplateBase extends CheckTemplate{
        @Override
        protected void identity() {
            System.out.println("basecheck identity");
        }

        @Override
        protected void creditHistory() {
            System.out.println("basecheck creditHistory");
        }

        @Override
        protected void incomeHistory() {
            System.out.println("basecheck incomeHistory");
        }
    }

    static class CheckCompany extends CheckTemplateBase{
        @Override
        protected void incomeHistory() {
            System.out.println("check company");
        }
    }

    //test
    public static void main(String[] args) {
        CheckCompany checkCompany = new CheckCompany();
        checkCompany.check();
    }
    
}

Description:
1. Define a check template CheckTemplate, the abstract check method of protected is defined in the template, mainly not to provide external calls. The check() method provides the check flow for yes.
2. Declare the check template and then declare the base class CheckTemplateBase for checking, mainly to provide a default implementation, and all check classes can inherit this base class.
3. Finally, the specific type to be checked, CheckCompany, inherits the CheckTemplateBase class, and can implement a specific check method.

java8 function jdk8 functional programming implementation, using "functional interface"

Code:

public class TemplateTest{

    /**
     * function interface
     */
    interface Criteria{
        void check();
    }

    /**
     * Template
     */
    static class CheckTemplate {
        // function interface as property
        private final Criteria identity;
        private final Criteria creditHistory;
        private final Criteria incomeHistory;

        public CheckTemplate(Criteria identity,
                             Criteria creditHistory,
                             Criteria incomeHistory) {
            this.identity = identity;
            this.creditHistory = creditHistory;
            this.incomeHistory = incomeHistory;
        }

        //template method
        public void checkLoanApplication(){
            identity.check();
            creditHistory.check();
            incomeHistory.check();
        }
    }


    /**
     * The default check class, each method corresponds to a functional interface
     * All processing subclass implementations can inherit from this class
     */
    static class CheckBase {
        public void identity() {
            System.out.println("basecheck identity");
        }
        public void creditHistory() {
            System.out.println("basecheck creditHistory");
        }
        public void incomeHistory() {
            System.out.println("basecheck incomeHistory");
        }
    }

    /**
     * an examination
     */
    static class Check extends CheckTemplate {
        public Check(CheckBase check) {
            //Incoming all function interface
            super(check::identity,
                    check::creditHistory,
                    check::incomeHistory);
        }
    }

    /**
     * Company processing flow
     *
     */
    static class CompanyCheck extends CheckBase {
        //Override the creditHistory method
        public void creditHistory(){
            System.out.println("company creditHistory ");
        }
    }


    public static void main(String[] args) {
        Check c = new Check(new CompanyCheck());
        c.checkLoanApplication();
    }

}
Description:
1. First declare a functional interface Criteria, define a check method check()
2. Declare the check template CheckTemplate, declare the Criteria attribute in the template, which is used as the definition of the inspection process, each Criteria attribute corresponds to a check part of the process.

3. Check base class CheckBase Mainly to provide a default implementation, all check classes can inherit this base class.

 4. Declare the specific check CompanyCheck extends CheckBase, you can customize the content of the check, and use the default if it is not defined.

5. Declare the check class Check extends CheckTemplate, declaring that a constructor parameter is the check base class (interface can also) CheckBase. There are two functions: a: the base class for all classes with rest check, b: the parameter of the Check construction method, as long as it is a CheckBase subclass, the Check can be constructed, and the code is clear and standardized. In the constructor, the constructor of the parent class is called directly, and the parameter is the "function interface".

java8 final code:

public class TemplateTest{

    /**
     * function interface
     */
    interface Criteria{
        void check();
    }

    /**
     * Template
     */
    static class CheckTemplate {
        // function interface as property
        private final Criteria identity;
        private final Criteria creditHistory;
        private final Criteria incomeHistory;

        public CheckTemplate(Criteria identity,
                             Criteria creditHistory,
                             Criteria incomeHistory) {
            this.identity = identity;
            this.creditHistory = creditHistory;
            this.incomeHistory = incomeHistory;
        }

        //template method
        public void checkLoanApplication(){
            identity.check();
            creditHistory.check();
            incomeHistory.check();
        }
    }

    /**
     * The default check class, each method corresponds to a functional interface
     * All processing subclass implementations can inherit from this class
     */
    static class CheckBase {
        public void companyIdentity() {
            System.out.println("company identity");
        }
        public void companyCreditHistory() {
            System.out.println("company creditHistory");
        }
        public void companyIncomeHistory() {
            System.out.println("company incomeHistory");
        }
        //Revenue check for large companies
        public void bigCompanyIncomeHistory() {
            System.out.println("big company incomeHistory");
        }

    }

    public static void main(String[] args) {
        CheckBase checkBase = new CheckBase();
        CheckTemplate checkTemplate =  new CheckTemplate(checkBase::companyIdentity,checkBase::companyCreditHistory,checkBase::bigCompanyIncomeHistory);
        checkTemplate.checkLoanApplication();

    }

}



Comparison of the two implementations:

The first implementation requires that each object to be checked must be created with a specific class, and the implementation of java8 can directly pass in the "function interface".

A specific class is declared in the example, and all check methods (specific methods) can also be declared in the CheckBase class, and the "function" can be directly passed in according to different check objects, thus avoiding the creation of each check object. a class.




Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326929539&siteId=291194637