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的后置通知执行。。。"); } }