模板模式+代理模式实战模拟

package com.demo.model.template;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

//

/**
 * 模板模式+代理模式实战模拟
 *
 * 优点
 * 封装不变部分,扩展可变部分,可在指定步骤随意扩展,只需要加一个advice实现,在init()方法中add实现类即可
 *
 *
 */
public class TemplateTest {

    /**
     * 可以在spring初始化后调用
     * @PostConstruct 注解可以解决这个问题
     */
    public static void init(){
        AdviceProxy.add(new Advice01Impl());
        AdviceProxy.add(new Advice02Impl());
    }

    public static void main(String[] args) {

        //可以在spring初始化后调用
        //@PostConstruct 注解可以解决这个问题
        init();

        AbstractTemplate template = new AdviceProxy();
        //---------------调用模板流程
        template.templateMethod();
    }

}

/**
 * 模板抽象类
 */
abstract class AbstractTemplate{

    void templateMethod(){
        abstractMethod1();
        specificMethod();
        abstractMethod2();
    }
    //封装不变部分
    private void specificMethod(){
        System.out.println("不变的逻辑执行");
    }
    //扩展可变部分
    abstract void abstractMethod1();
    abstract void abstractMethod2();
}

/**
 * 代理类+抽象模板子类的结合
 * 功能
 *
 *
 */
class AdviceProxy extends AbstractTemplate {

    //所有实现Advice的子类
    private static List<Advice> adviceList = new ArrayList();

    /**
     * 添加被代理对象的引用
     * @param advice
     */
    public static void add(Advice advice) {
        adviceList.add(advice);
    }

    /**
     * 抽象模板类的可扩展方法
     */
    @Override
    void abstractMethod1() {
        //会执行所有实现Advice的begin()方法
        System.out.println("代理方法1执行。。。");
        //param:Consumer接口的匿名实现,实现方法中调用begin()方法,e:是上面execute()的for循环中调用时传入( consumer.accept(advice);)
        execute(e->{e.begin();});
    }

    /**
     * 抽象模板类的可扩展方法
     */
    @Override
    void abstractMethod2() {
        //会执行所有实现Advice的after()方法
        System.out.println("代理方法2执行。。。");
        execute(e->{e.after();});
    }

    /**
     *
     * 函数式编程Consumer应用
     * 作用:
     * 循环Advice接口的所有实现类,调用未实现的方法accept(),当前实现类为参数,当调用此方法时再实现方法accept(),函数式编程的统一用法
     * @param consumer
     */
    private void execute(Consumer<Advice> consumer) {
        for (Advice advice : adviceList) {
            consumer.accept(advice);
        }
    }
}


/**
 * 通知的抽象
 */
interface Advice {
    /**
     * 前置通知
     */
    void begin();

    /**
     * 后置通知
     */
    void after();
}

/**
 * 通知具体实现01
 * 可以通过Spring的@Bean注解托管给spring
 */
class Advice01Impl implements Advice {

    @Override
    public void begin() {
        System.out.println("业务步骤二:具体实现01的前置通知执行。。。");
    }

    @Override
    public void after() {
        System.out.println("业务步骤最后一步:具体实现01的后置通知执行。。。");
    }
}

/**
 * 通知具体实现02
 * 可以通过Spring的@Bean注解托管给spring
 */
class Advice02Impl implements Advice {

    @Override
    public void begin() {
        System.out.println("业务步骤二:具体实现02的前置通知执行。。。");
    }

    @Override
    public void after() {
        System.out.println("业务步骤最后一步:具体实现02的后置通知执行。。。");
    }
}

 

posted @ 2019-09-25 16:55  史安良  阅读(439)  评论(0编辑  收藏  举报