一、什么是代理模式?
代理模式(Proxy Pattern):即一个类别可以作为其它东西的接口。这种类型的设计模式属于结构型模式。在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。
二、代理模式的角色和职责
subject: 真实主题与代理主题的共同接口。
RealSubject:定义了代理角色所代表的真实对象。
Proxy:代理角色内部包含有对真实对象的引用,所以它可以操作真实对象,同时也可以附加其他的操作,相当于对真实对象进行封装。
三、优缺点及应用场景:
优点:
1、代理模式能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。
2、代理对象可以在客户端和目标对象之间起到中介的作用,如在虚拟代理中,可以通过使用一个小对象来代表一个大对象,从而减少系统资源的消耗,对系统进行优化并提高运行速度。缺点:
1、在客户端和真实主题之间增加了代理对象, 可能会造成请求的处理速度变慢。
2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。应用环境:
1、 远程代理:为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实。
2、 虚拟代理:通过使用过一个小的对象代理一个大对象。这样就可以减少系统的开销。
3、 保护代理:用来控制对真实对象的访问权限。
四、具体代码:
1>:静态代理
/**
* @Title: Subject.java
* @Package
* @Description: Subject接口
* @author xiaozhi
* @date 2016年12月6日 下午6:53:34
* @version V1.0
*/
public interface Subject {
public void sellBook();
}
/**
* @Title: RealSubject.java
* @Package
* @Description: 真实产品
* @author xiaozhi
* @date 2016年12月6日 下午6:53:51
* @version V1.0
*/
public class RealSubject implements Subject {
@Override
public void sellBook() {
System.out.println("卖书");
}
}
/**
* @Title: ProxySubject.java
* @Package
* @Description: 代理类
* @author xiaozhi
* @date 2016年12月6日 下午6:54:04
* @version V1.0
*/
public class ProxySubject implements Subject {
// 引用真实产品类
private RealSubject realSubject;
public void setRealSubject(RealSubject realSubject) {
this.realSubject = realSubject;
}
@Override
public void sellBook() {
dazhe();
if (realSubject == null) {
realSubject = new RealSubject();
}
this.realSubject.sellBook();
give();
}
public void dazhe() {
System.out.println("打折");
}
public void give() {
System.out.println("赠送代金卷");
}
}
/**
* @Title: MainClass.java
* @Package
* @Description: 静态代理测试类
* @author xiaozhi
* @date 2016年12月6日 下午6:53:16
* @version V1.0
*/
public class MainClass {
public static void main(String[] args) {
RealSubject rs = new RealSubject();
rs.sellBook();
System.out.println("。。。。。。。。。。。。。。。");
ProxySubject ps = new ProxySubject();
ps.sellBook();
}
}
2>:动态代理:
package com.Proxy.dynamic;
/**
* @Title: Subject.java
* @Package
* @Description: TODO(用一句话描述该文件做什么)
* @author xiaozhi
* @date 2016年12月6日 下午6:53:34
* @version V1.0
*/
public interface Subject {
public void sellBook();
}
package com.Proxy.dynamic;
/**
* @Title: RealSubject.java
* @Package
* @Description: TODO(用一句话描述该文件做什么)
* @author xiaozhi
* @date 2016年12月6日 下午6:53:51
* @version V1.0
*/
public class RealSubject implements Subject {
@Override
public void sellBook() {
System.out.println("卖书");
}
}
/**
* @Title: MyHandle.java
* @Package com.Proxy.dynamic
* @Description: 通过注解和反射机制动态代理
* @author xiaozhi
* @date 2016年12月6日 下午7:12:18
* @version V1.0
*/
package com.Proxy.dynamic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyHandler implements InvocationHandler {
private RealSubject realSubject;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
dazhe();
result = method.invoke(realSubject, args);
give();
return result;
}
public void dazhe() {
System.out.println("打折");
}
public void give() {
System.out.println("赠送代金卷");
}
public RealSubject getRealSubject() {
return realSubject;
}
public void setRealSubject(RealSubject realSubject) {
this.realSubject = realSubject;
}
}
/**
* @Title: Main.java
* @Package com.Proxy.dynamic
* @Description: TODO(用一句话描述该文件做什么)
* @author xiaozhi
* @date 2016年12月6日 下午7:11:21
* @version V1.0
*/
package com.Proxy.dynamic;
import java.lang.reflect.Proxy;
public class MainClass {
public static void main(String[] args) {
RealSubject rs = new RealSubject();
MyHandler myHandler = new MyHandler();
myHandler.setRealSubject(rs);
Subject ProxySubject = (Subject) Proxy.newProxyInstance(rs.getClass().getClassLoader(),
rs.getClass().getInterfaces(), myHandler);
ProxySubject.sellBook();
}
}
五、测试结果:
<1>
卖书
。。。。。。。。。。。。。。。
打折
卖书
赠送代金卷
<2>
打折
卖书
赠送代金卷