1.代理模式作用:
为其他对象提供一种代理以控制对这个对象的访问。(类似中介,可以为你做事,也同时实现自己的事。例如找房子,中介可以实现租房,同时中介可以收取一定费用)代理访问你要访问对象(中介代替租房者去访问房东租房)。
2.代理角色:
- 抽象角色:声明真实对象和代理对象的共同接口。(例如租房(租房是接口的一个行为),中介和房东都能完成租房的这个动作)
- 代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以再执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。(中介就是代理角色)
- 真实角色:代理角色所代表的真实对象,是最终要引用的对象。(真实角色是房东)
package com.test.proxy;
/**
* 定义一个抽象类,静态代理模式可以使用接口或者抽象类
* @author 守望幸福
*
*/
public abstract class Subject {
public abstract void request();
}
package com.test.proxy;
/**
* 代理类实现Subject抽象类,同时拥有真实对象的引用(private RealSubject realSubject;)
* 代理必须完成真实对象的动作,也可以添加自己的动作。
* @author 守望幸福
*
*/
public class ProxySubject extends Subject {
private RealSubject realSubject;//代理角色内部引用真实角色
@Override
public void request() {
this.perRequest();//调用真实类之前调用
if(realSubject==null){
realSubject=new RealSubject();
realSubject.request();//真实角色完成的事情
}
this.postRequest();//调用真实类之后调用
}
private void perRequest(){
System.out.println(" per Request!");
}
private void postRequest(){
System.out.println(" post Request!");
}
}
package com.test.proxy;
/**
* 真实类实现接口(Subject)
* @author 守望幸福
*
*/
public class RealSubject extends Subject{
@Override
public void request() {
System.out.println("from realSubject");
}
}
package com.test.proxy;
/**
* 客户端调用类
* @author 守望幸福
*
*/
public class Client {
public static void main(String[] args) {
Subject s=new ProxySubject();
s.request();
}
}
从上例可以观察出,客户实际需要调用的是RealSubject类的request方法,现在通过代理类ProxySubject来代理真实类,也能同样达到调用request的目的 ,同时还封装了其他的方法preRequest、postRequest,来出来另外的问题。
如果按照上诉的方使用代理模式,那么真实角色必须是实现已存在,并将其作为代理对象的内部属性。事实上,一个真实角色必须对应一个代理角色,如果大量使用会导致类的急剧膨胀,而且无法处理事先未知的真实角色。上述问题可以通过动态代理 来解决。