裝飾模式
一:装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的。
10 public String operation(){
11 return com.operation()+cl;//位置互换
12 }
二:装饰者和被装饰者有共同的基类,我们利用继承达到“类型匹配”,而不是利用继承获得“行为”,新行为由组合对象得来的。
10 public String operation(){
11 return com.operation()+cl;//接口回调具体被装饰者和具体装饰者的operation()方法
12 }
注:抽象装饰者可有可无
1 //抽象被裝飾者 2 public abstract class Component{ 3 private String lsh="output:";//output:生成流水號 4 public abstract String operation();//抽象方法(包裝) 5 public String getlsh(){ 6 return lsh; 7 } 8 }
1 //具體被裝飾者 2 public class detailComponent extends Component { 3 @Override 4 public String operation(){ 5 return getlsh(); 6 } 7 }
1 //具體裝飾者:常量 2 public class constant extends Component { 3 private Component com; 4 private String cl; 5 public constant(Component com, String cl){ 6 this.com=com; 7 this.cl=cl; 8 } 9 @Override 10 public String operation(){ 11 return com.operation()+cl; 12 } 13 }
1 //具體裝飾者:自增數 2 public class num extends Component { 3 private Component com; 4 private String num; 5 public num (Component com, String num){ 6 this.com=com; 7 this.num=num; 8 } 9 @Override 10 public String operation(){ 11 return com.operation()+num; 12 } 13 }
1 //具體裝飾者:日期 2 public class time extends Component { 3 private Component com; 4 private String rq; 5 public time (Component com, String rq){ 6 this.rq=rq; 7 this.com=com; 8 } 9 @Override 10 public String operation(){ 11 return com.operation()+rq; 12 } 13 }
1 //測試 2 public class test { 3 public static void main(String[] args) { 4 //客戶端傳來 三個 規則 5 String a = "DB"; 6 String b = "YYYY"; 7 String c = "001"; 8 //當前時間 字符串 9 b = cDate(b); 10 Component com = new detailComponent();//創建 被裝飾者 11 com = new num(new time(new constant(com,a),b),c);//裝飾 12 System.out.println(com.operation());//輸出為:output:DB2020001 13 Component com2 = new detailComponent();//創建 被裝飾者 14 c = autoNum(c);//c+1 15 com2 = new num(new time(new constant(com2,a),b),c); 16 System.out.println(com2.operation());//輸出為:output:DB2020002 17 } 18 public static String autoNum(String c){ 19 StringBuilder strbd = new StringBuilder(); 20 int i,j; 21 i = Integer.parseInt(c); 22 i++; 23 int d = c.length()-Integer.toString(i).length(); 24 j=0; 25 while(j<d){ 26 j++; 27 strbd.append("0"); 28 } 29 strbd.append(i); 30 return strbd.toString(); 31 } 32 public static String cDate(String b){ 33 SimpleDateFormat dateFormat ; 34 String str = null; 35 if(b.length()==8) { 36 str = "YYYYMMDD"; 37 } 38 else if(b.length()==6){ 39 str = "YYYYMM"; 40 } 41 else if(b.length()==4){ 42 str = "YYYY"; 43 }else { 44 return "error"; 45 } 46 dateFormat = new SimpleDateFormat(str); 47 String currentDate = dateFormat.format(new Date()); 48 return currentDate; 49 } 50 }
代理模式
靜態代理
1 //目標接口 2 public interface Star { 3 public void show(); 4 public void sing(); 5 } 6 //工具 7 public class Tool { 8 private String microphone; 9 private String cap; 10 public tool(){} 11 public setMicrophone(String microphone){ 12 this.microphone=microphone; 13 } 14 public getMicrophone(){ 15 return microphone; 16 } 17 public setCap(String cap){ 18 this.cap=cap; 19 } 20 public getCap(){ 21 return cap; 22 } 23 } 24 //目標對象 25 public class Chris implements Star { 26 public Chris(){} 27 public void show(){ 28 System.out.println("表演了魔術。"); 29 } 30 public void sing(){ 31 System.out.println("唱了一首海闊天空。"); 32 } 33 } 34 //代理類 35 public class Proxy implements Star { 36 private Tool tool; 37 private Star star; 38 public Proxy(Tool tool,Star star){ 39 this.tool=tool; 40 this.Star=star; 41 } 42 @Override 43 public void show(){ 44 tool.setCap("魔術帽"); 45 System.out.println("start:"+getCap()); 46 star.show(); 47 System.out.println("over"); 48 } 49 public void sing(){ 50 tool.setMicrophone("藍牙麥克風"); 51 System.out.println("start:"+getMicrophone()); 52 star.sing(); 53 System.out.println("over"); 54 } 55 } 56 //客戶端 57 public class client { 58 public static void main(String[] args){ 59 Proxy proxy = new (new Tool(),new Chris()); 60 proxy.sing(); 61 proxy.show(); 62 } 63 }
動態代理(JDK動態代理)
动态代理的对象必须实现一个或多个接口
1 //調用處理程序 2 public class ProxyFactory{ 3 private Object target; 4 public ProxyFactory(Object target){ 5 this.target=target; 6 } 7 public Object getProxyInstance(){ 8 return Proxy.newProxyInstance(//生成代理實例 9 target.getClass().getClassLoader(),//类加载器 10 target.getClass().getInterfaces(),//增强方法所在的类实现的一个或多个接口 11 new InvocationHandler() {//調用代理實例 12 /* 13 *proxy 生成的代理實例 14 *method 代理實例被調用的方法 15 *args 代理實例被調用的方法參數 16 */ 17 @Override 18 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 19 System.out.println("事務1"); 20 Object returnValue = method.invoke(target, args); 21 System.out.println("事務2"); 22 return returnValue; 23 } 24 } 25 ); 26 } 27 } 28 //客戶端2 29 public class client { 30 public static void main(String[] args){ 31 Star target = new Chris(); 32 System.out.println(target.getClass());//...Chris.class 33 Star proxy = (Star)new ProxyFactory(target).getProxyInstance();//...$Proxy0.class 34 proxy.show(); 35 proxy.sing(); 36 } 37 }
動態代理(CGLIB動態代理)
动态代理的对象沒有实现接口
1 //目標對象 2 public class Chris { 3 public Chris(){} 4 public void show(){ 5 System.out.println("表演了魔術。"); 6 } 7 public void sing(){ 8 System.out.println("唱了一首海闊天空。"); 9 } 10 } 11 public class ProxyFactory implements MethodInterceptor{ 12 private Object target; 13 public ProxyFactory(Object target) { 14 this.target = target; 15 } 16 public Object getProxyInstance(){//生成代理實例 17 Enhancer en = new Enhancer();//工具類 18 en.setSuperclass(target.getClass());//設置父類 19 en.setCallback(this);//設置回調函數 20 return en.create();//創建子類 21 } 22 23 @Override 24 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {//調用代理實例 25 System.out.println("事務1"); 26 Object returnValue = method.invoke(target, args); 27 System.out.println("事務2"); 28 return returnValue; 29 } 30 } 31 //客戶端3 32 public class client { 33 public static void main(String[] args){ 34 Chris target = new Chris(); 35 System.out.println(target.getClass());//...Chris.class 36 Chris proxy = (Chris)new ProxyFactory(target).getProxyInstance();//...$Proxy0.class 37 proxy.show(); 38 proxy.sing(); 39 } 40 }
Spring AOP
面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术,AOP是OOP(面向对象编程)的延续。
利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,動態添加功能:日誌,安全,事務等。
1.通知(Advice):安全,事务,日志等功能
2.连接点(JoinPoint):spring允许你使用通知的地方
3.切入点(Pointcut):切点来筛选连接点,选中那几个你想要的方法
4.切面(Aspect):切面是通知和切入点的结合
5.引入(introduction):把切面用到目標方法
6.目标(target):目标类,也就是要被通知的对象,也就是真正的业务逻辑
7.代理(proxy):代理
8.织入(weaving):把切面应用到目标对象来创建新的代理对象的过程
参考文章:
代理模式
https://www.cnblogs.com/echola/p/11004069.html
https://segmentfault.com/a/1190000019433930?utm_source=tag-newest
裝飾模式
https://www.cnblogs.com/ZhangHaoShuaiGe/p/7866610.html