代理模式为另一个对象提供一个替身或占位符以控制对这个对象的访问。
示例—建立评价系统
每个人都有基本属性,包括:名字、性别、兴趣、评价率。需要对每个人的访问进行控制,对名字、性别、兴趣只能自己修改,别人不能修改。评价必须由其他人访问,自己不能评价。
UML图表示
代理模式代码演示
人的接口
package Proxy;
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);
}
人的实现类
package Proxy;
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++;
}
}
拥有者的动态调用类
package Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
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 IllegalAccessException {
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;
}
}
非拥有者的动态调用类
package Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class NonOwnerInvocationHandler implements InvocationHandler {
PersonBean person;
public NonOwnerInvocationHandler(PersonBean person){
this.person = person;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws IllegalAccessException {
try {
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();
}
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
测试代码
package Proxy;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
public class CommentTestDrive {
Map<String,PersonBean> data;
/**
* 动态生成拥有者代理类
* @param person
* @return
*/
PersonBean getOwnerProxy(PersonBean person){
return (PersonBean) Proxy.newProxyInstance(person.getClass().getClassLoader(),
person.getClass().getInterfaces(),new OwnerInvocationHandler(person));
}
/**
* 动态生成非拥有者代理类
* @param person
* @return
*/
PersonBean getNonOwnerProxy(PersonBean person){
return (PersonBean) Proxy.newProxyInstance(person.getClass().getClassLoader(),
person.getClass().getInterfaces(),new NonOwnerInvocationHandler(person));
}
/**
* 初始化数据
*/
void initializeDatabase(){
data = new HashMap<String, PersonBean>();
PersonBean person = new PersonBeanImpl();
person.setName("Joe Javabean");
person.setGender("male");
person.setInterests("swimming");
person.setHotOrNotRating(7);
data.put("Joe", person);
}
public CommentTestDrive(){
initializeDatabase();
}
public void drive(){
PersonBean joe = data.get("Joe");
System.out.println("His info is :");
System.out.println("name is " + joe.getName());
System.out.println("gender is " + joe.getGender());
System.out.println("interests is " + joe.getInterests());
System.out.println("rating is " + joe.getHotOrNotRating());
System.out.println("~~~~~~~~~~~~~~~");
PersonBean ownerProxy = getOwnerProxy(joe);
System.out.println("Name is " + ownerProxy.getName());
ownerProxy.setInterests("bowling, Go");
System.out.println("Interests set from owner proxy");
try {
ownerProxy.setHotOrNotRating(10);
}
catch (Exception e){
System.out.println("Can't set rating from owner proxy");
}
System.out.println("Rating is " + ownerProxy.getHotOrNotRating());
PersonBean nonOwnerProxy = getNonOwnerProxy(joe);
System.out.println("Name is " + nonOwnerProxy.getName());
try {
nonOwnerProxy.setInterests("bowling, Go");
}
catch (Exception e){
System.out.println("Can't set interests from non owner proxy");
}
nonOwnerProxy.setHotOrNotRating(3);
System.out.println("Rating set from non owner proxy");
System.out.println("Rating is " + nonOwnerProxy.getHotOrNotRating());
System.out.println("~~~~~~~~~~~~~~~");
System.out.println("Now his info is :");
System.out.println("name is " + joe.getName());
System.out.println("gender is " + joe.getGender());
System.out.println("interests is " + joe.getInterests());
System.out.println("rating is " + joe.getHotOrNotRating());
}
public static void main(String[] args) {
CommentTestDrive drive = new CommentTestDrive();
drive.drive();
}
}
测试结果
His info is :
name is Joe Javabean
gender is male
interests is swimming
rating is 7
~~~~~~~~~~~~~~~
Name is Joe Javabean
Interests set from owner proxy
Can't set rating from owner proxy
Rating is 7
Name is Joe Javabean
Can't set interests from non owner proxy
Rating set from non owner proxy
Rating is 5
~~~~~~~~~~~~~~~
Now his info is :
name is Joe Javabean
gender is male
interests is bowling, Go
rating is 5
网友评论