代理模式

代理模式

定义与类型

定义:为其他对象提供一种代理,以控制对这个对象的访问

代理对象在客户端和目标对象之间起到中介的作用

类型:结构形

 

适用场景

(1)      保护目标对象

(2)      增强目标对象

代理-优点

代理模式能将代理对象与真实被调用的目标对象分离

在一定程度上降低了系统的耦合度,扩展性好

保护目标对象

增强目标对象

代理-缺点

代理模式会造成系统设计中类的数目增加(增加了代理类)

在客户端和目标对象之间增加了一个代理对象,会造成请求处理速度变慢

增加了系统的复杂度

 

代理-扩展

静态代理

动态代理

 

例子(静态代理)

定义一个接口

public interface Interface {
void doSomething();
void somethingElse(String arg);
}

写一个目标对象实现接口
public class RealObject implements Interface {
@Override
public void doSomething() {
System.out.println("doSomething");
}

@Override
public void somethingElse(String arg) {
System.out.println("somethingElse" + arg);
}

}
写一个代理对象对目标对象进行代理,参数由构造方法传入
public class SimpleProxy implements Interface {
private Interface proxied;

public SimpleProxy(Interface proxied) {
this.proxied = proxied;
}

@Override
public void doSomething() {
System.out.println("SimpleProxy doSomething");
proxied.doSomething();
}

@Override
public void somethingElse(String arg) {
System.out.println("SimpleProxy somethingElse" + arg );
proxied.somethingElse(arg);
}
}

测试

public class SimpleProxyDemo {
public static void consumer(Interface iface){
iface.doSomething();
iface.somethingElse("bonobo");
}
public static void main(String[] args) {
consumer(new RealObject());
consumer(new SimpleProxy(new RealObject()));
}
}

输出:

  doSomething
  somethingElsebonobo
  SimpleProxy doSomething
  doSomething
  SimpleProxy somethingElsebonobo
  somethingElsebonobo

UML

 

用动态代理进行改进

编写代理逻辑

public class DynamicProxyHandler implements InvocationHandler {
private Object proxied;

public DynamicProxyHandler(Object proxied) {
this.proxied = proxied;
}

/**
*
* @param proxy 调用改方法的代理实例
* @param method 需要进行代理的方法
* @param args 需要代理的方法的参数
* @return 返回的是方法的执行结果
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("*** proxy: " + proxy.getClass() + " .method: " + method + ",args: " + args);
if(args != null){
for(Object arg : args){
System.out.println(" " + arg);
}
}

return method.invoke(proxied,args); //执行这个方法并返回执行后的结果
}

}

测试

public class SimpleDynamicProxy {
public static void consumer(Interface iface){
iface.doSomething();
iface.somethingElse("bonobo");
}
public static void main(String[] args) {
RealObject real = new RealObject();
consumer(real);

//insert a proxy and call again;
Interface proxy = (Interface) Proxy.newProxyInstance(Interface.class.getClassLoader(),
new Class[]{Interface.class},new DynamicProxyHandler(real));
consumer(proxy);
}
}

输出:

  doSomething
  somethingElsebonobo
  *** proxy: class com.sun.proxy.$Proxy0 .method: public abstract void proxy.staticproxy.Interface.doSomething(),args: null
  doSomething
  *** proxy: class com.sun.proxy.$Proxy0 .method: public abstract void proxy.staticproxy.Interface.somethingElse(java.lang.String),args: [Ljava.lang.Object;@4b67cf4d
  bonobo
  somethingElsebonobo

可见在执行实际方法前执行了代理逻辑

 

posted @ 2020-04-08 17:16  叫熊猫啊  阅读(152)  评论(0编辑  收藏  举报