设计模式(二十九)------23种设计模式(21):代理模式
使用频率:★★★★☆
一、什么是代理模式
通过代理对象间接控制并访问目标对象的方法;
二、补充说明
想到代理模式,容易让人想到AOP思想,Spring中的AOP可以通过动态代理实现;
代理模式有静态代理和动态代理两种;
解耦调用者和被调用者;
三、角色
抽象主题,定义一些需要代理的方法
具体主题,实现一些具体逻辑
代理主题,代理和封装具体主题
客户端Main:调用者,通过代理主题访问具体主题
四、例子,JAVA实现
这里我们模拟代理上网场景:应用服务器返回信息给代理服务器,代理服务器返回信息给客户端;
抽象主题,服务器接口,有一个response方法,能够返回信息
1 package com.pichen.dp.structuralpattern.proxy; 2 public interface Server { 3 4 public String response(); 5 }
具体主题,某个具体的应用服务器
1 package com.pichen.dp.structuralpattern.proxy; 2 public class ApplicationServer implements Server{ 3 4 @Override 5 public String response() { 6 //System.out.println("response from ApplicationServers。"); 7 return "response from ApplicationServers"; 8 } 9 10 }
静态代理主题角色, 对具体主题的直接引用,直接调用具体主题里的方法
1 package com.pichen.dp.structuralpattern.proxy; 2 public class StaticProxyServer implements Server { 3 4 private ApplicationServer appServer; 5 @Override 6 public String response() { 7 //System.out.println("response from ProxyServer。"); 8 if(null == appServer){ 9 appServer = new ApplicationServer(); 10 } 11 //before , you can do something 12 String str = appServer.response() + "(by ProxyServer, static proxy.)"; 13 //after , you can do something 14 return str; 15 } 16 17 }
动态代理InvocationHandler,可以通过它获取动态代理主题角色,代理对象是在运行期间动态生成的;
1 package com.pichen.dp.structuralpattern.proxy; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 import java.lang.reflect.Proxy; 6 7 public class DynamicProxyServerHandler implements InvocationHandler{ 8 9 private Server appServer; 10 11 public DynamicProxyServerHandler(Server appServer) { 12 this.appServer = appServer; 13 } 14 15 //获取动态代理对象 16 public Object getProxyyServer(){ 17 return Proxy.newProxyInstance(appServer.getClass().getClassLoader(), 18 appServer.getClass().getInterfaces(), this); 19 } 20 21 @Override 22 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 23 //before , you can do something 24 Object str = method.invoke(appServer, args); 25 //after , you can do something 26 return str.toString() + "(by ProxyServer, dynamic proxy.)"; 27 } 28 29 }
客户端,Main类,通过代理服务器获取应用服务器的返回信息
1 package com.pichen.dp.structuralpattern.proxy; 2 3 public class Main { 4 public static void main(String[] args) { 5 //静态代理 6 Server staticProxyServer = new StaticProxyServer(); 7 System.out.println(staticProxyServer.response()); 8 9 //动态代理 10 DynamicProxyServerHandler dpshandler = new DynamicProxyServerHandler(new ApplicationServer()); 11 Server dynamicProxyServer = (Server) dpshandler.getProxyyServer(); 12 System.out.println(dynamicProxyServer.response()); 13 } 14 }
结果打印
response from ApplicationServers(by ProxyServer, static proxy.) response from ApplicationServers(by ProxyServer, dynamic proxy.)