一:相关定义
代理模式:为另一个对象提供一个替身或占位符以控制对这个对象的访问。
二:相关类图和示例
代理模式类图:
看类图和装饰者模式很像,但两者的目的不同,代理强调的是控制对象的访问。代理有很多的应用场景和分类,这里我们主要来看一下java中的动态代理如何工作,因为它比较常用嘛,下面看类图。
因为java已经为你创建了Proxy类,所以你需要有办法来告诉Proxy类你要做什么。你不能像之前一样把代码放在Proxy类中,而需要放在InvocationHandler中。InvocationHandler的工作是响应代理的任何调用,你可以把InvocationHandler想成是代理收到方法调用后,请求做实际工作的对象。
下面看示例代码:
public interface PersonBean {
String getName();
String getGender();
String getInterests();
int getHotOrNotRating();
void setName();
void setGender();
void setInterests();
void setHotOrNotRating();
}
public class PersonBeanImpl implements PersonBean{
String name;
String gender;
String interests;
int rating;
int ratingCount = 0;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getInterests() {
return interests;
}
public void setInterests(String interests) {
this.interests = interests;
}
public int getHotOrNotRating(){
if (ratingCount == 0) return 0;
return (rating/ratingCount);
}
public void setHotOrNotRating(int rating){
this.rating += rating;
ratingCount++;
}
}
下面开始创建代理处理器:
一:创建InvocationHandler
public class OwnerInvocationHandler implements InvocationHandler{
PersonBean person;
public OwnerInvocationHandler(PersonBean person){
this.person = person;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args
) throws Throwable {
try {
if (method.getName().startsWith("get")){
return method.invoke(person, args);
}else if (method.getName().equals("setHotOrNotRating")){
throw new IllegalAccessException();
}else if (method.getName().startsWith("set")){
return method.invoke(person, args);
}
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
二:实例化Proxy对象
PersonBean getOwnerProxy(PersonBean person){
return (PersonBean) Proxy.newProxyInstance(
person.getClass().getClassLoader(),
person.getClass().getInterfaces(),
new OwnerInvocationHandler(person)
);
}
使用Proxy创建的对象就是我们的代理对象,使用时可以通过它们共同的接口PersonBean来进行使用。
参考书籍:《head first 设计模式》