1.代理(proxy)模式的定义
代理模式:控制和管理访问。
代理模式的定义:代理模式为另一个对象提供一个替身或者占位符以控制对这个对象的访问。
使用代理模式的范围:使用代理模式创建代表对象,让代表对象控制某对象的访问,被代理的对象可以使远程对象、创建开销大的对象或者需要安全控制的对象。
2.远程代理(remote proxy)
远程代理,即远程对象的本地代表。
远程对象:即一种对象,活在不同的java虚拟机堆中,也就是在不同地址空间运行的远程对象。
本地代表:一种可以由本地方法调用的对象。
java中使用RMI实现远程调用。
3.虚拟代理(virtual proxy)
虚拟代理作为创建开销大的对象的代表,当真正需要一个对象时才创建它。
例子:显示加载网络图片,接口Icon,真正的对象ImageIcon,代理ImageProxy
public interface icon {
public void paintIcon(final Component c);
}
class ImageIcon implements Icon{
public ImageIcon(String imageUrl) {
//获取网络图片,耗时操作。
}
public void paintIcon(final Component c) {
}
}
class ImageProxy implements Icon {
ImageIcon imageIcon;
String imageUrl;
public ImageIcon(String imageUrl) {
this.imageUrl = imageUrl;
}
public void paintIcon(final Component c) {
if(imageIcon != null) {
imageIcon.paintIcon(c);
} else {
//开启线程处理开销大的操作,当处理完时然后重新处理图片
new Thread(new Runnable() {
public void run() {
imageIcon = new ImageIcon(imageUrl);
imageIcon.paintIcon(c);
}
}).start;
}
}
}
4.保护代理
使用的java的动态代理技术(反射)来实现对对象的控制访问。
例子:约会系统,自己可以修改自己的信息但是不能对自己评分,他人不可修改自己的信息,但是可以对其他人评分。
首先PersonBean定义访问的方法
package com.proxy.pattern;
public interface PersonBean {
String getName();
String getGender();// 性别
String getInterests();// 兴趣爱好
int getHotOrNotRating();// 评价
void setName(String name);
void setGender(String gender);
void setInterests(String interests);
void setHotOrNotRating(int rating);
}
PersonBeanImpl实现上述接口
package com.proxy.pattern;
//自己:不能给自己评分,但可修改个人信息。
//他人:可查看他人的信息,也可评分,但不可修改他人的信息。
public class PersonBeanImpl implements PersonBean {
String name;
String gender;
String interests;
int rating;
int ratingCount = 0;
@Override
public String getName() {
return name;
}
@Override
public String getGender() {
return gender;
}
@Override
public String getInterests() {
return interests;
}
@Override
public int getHotOrNotRating() {
if (ratingCount <= 0) {
return 0;
}
return rating / ratingCount;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public void setGender(String gender) {
this.gender = gender;
}
@Override
public void setInterests(String interests) {
this.interests = interests;
}
@Override
public void setHotOrNotRating(int rating) {
this.rating += rating;
ratingCount++;
}
}
NonOwerInvocationHandler类可以获取非自己 的调用者,可以调用他人的信息,但是不能修改,可以评分
package com.proxy.pattern;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class NonOwerInvocationHandler implements InvocationHandler {
PersonBean person;
NonOwerInvocationHandler(PersonBean person) {
this.person = person;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if (method.getName().startsWith("get")) {
return method.invoke(person, args);
} else if (method.getName().equals("setHotOrNotRating")) {
return method.invoke(person, args);
} else if (method.getName().startsWith("set")) {
throw new IllegalAccessException();
}
return null;<pre name="code" class="html">package com.proxy.pattern;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
//自己:不能给自己评分,但可修改个人信息。
public class OwnerInvocationHandler implements InvocationHandler {
PersonBean person;
OwnerInvocationHandler(PersonBean person) {
this.person = person;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
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);
}
return null;
}
}
}}
OwnerInvocationHandler可以获取修改自己的信息,但是不能评分
package com.proxy.pattern;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
//自己:不能给自己评分,但可修改个人信息。
public class OwnerInvocationHandler implements InvocationHandler {
PersonBean person;
OwnerInvocationHandler(PersonBean person) {
this.person = person;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
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);
}
return null;
}
}