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