zoukankan      html  css  js  c++  java
  • 模板模式+代理模式实战模拟

    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的后置通知执行。。。");
        }
    }
  • 相关阅读:
    一道B树的题目---先记一下, 还没看到B树
    一道二叉树的题目--后序遍历+中序遍历确定二叉树
    sonar 匿名内部类写法不推荐
    Springboot读取Jar文件中的resource
    一次单体测试的采坑--MatcherAssert.assertThat---org.hamcrest 和org.mockito
    B+树和B-树的区别
    一道二叉树题目--二叉树的顺序存储
    一道二叉树题目--根据先序序列和中序序列重画二叉树
    Jekins相关笔记
    POJ 1679 The Unique MST (最小生成树 Kruskal )
  • 原文地址:https://www.cnblogs.com/shianliang/p/11585896.html
Copyright © 2011-2022 走看看