什么是代理模式
代理模式为另一个对象提供替身或者占位符,以便控制客户对对象的访问,管理访问的方式有很多种。例如远程代理、虚拟代理、保护代理等。
远程代理:管理客户和远程对象之间的交互。
虚拟代理:控制访问实例化开销大的对象。
保护代理:基于调用者,控制对对象方法的调用。
类图
代码
案例:防止对person类的访问中,访问了不该访问的方法
以保护代理为例,主要是基于java内置的动态代理,来控制对对象方法的调用,其类图如下:
Person接口
java
public interface Person {
String getName();
String getGender();
String getInterests();
int getGeekRating();
void setName(String name);
void setGender(String gender);
void setInterests(String interests);
void setGeekRating(int rating);
}
Person实现类
java
public class PersonImpl implements Person{
String name;
String gender;
String interests;
int rating;
int ratingCount = 0;
public PersonImpl(String name, String gender, String interests, int rating, int ratingCount) {
this.name = name;
this.gender = gender;
this.interests = interests;
this.rating = rating;
this.ratingCount = ratingCount;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public int getGeekRating() {
if (ratingCount == 0) {
return 0;
} else {
return rating / ratingCount;
}
}
@Override
public void setGeekRating(int rating) {
this.rating += rating;
ratingCount++;
}
@Override
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String getGender() {
return gender;
}
@Override
public String getInterests() {
return interests;
}
@Override
public void setInterests(String interests) {
this.interests = interests;
}
NonOwnerInvocationHandler类
java
//InvocationHandler
public class NonOwnerInvocationHandler implements InvocationHandler {
Person person;
public NonOwnerInvocationHandler(Person 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("setGeekRating")) {
return method.invoke(person, args);
} else if (method.getName().startsWith("set")) {
throw new Throwable();
}
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
OwnerInvocationHandler类
java
public class OwnerInvocationHandler implements InvocationHandler {
Person person;
public OwnerInvocationHandler(Person 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("setGeekRating")) {
throw new Throwable();
} else if (method.getName().startsWith("set")) {
return method.invoke(person, args);
}
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
测试:
java
public class Test {
public static void main(String[] args) {
Person kang = new PersonImpl("kwb", "boy", "ball", 1, 3);
Person owner = getProxy.getOwnerProxy(kang);
System.out.println(owner.getName());
}
}
区别
装饰器模式为对象加上行为,而代理则是控制访问。