代理模式(Proxy Pattern)(三):HeadFirst使用java API创建一个保护代理

一、问题描述


使用java动态代理根据访问权限控制对客户信息的修改以保护客户信息,客户的信息包括:姓名name、性别gender、interests兴趣爱好、评分HotOrNot(类似于顶或踩),这些信息可以被所有用户看到,只有顾客可以修改自己的name、gender、interests,但是不能修改自己的评分,只能由其他人给他打分。

即根据权限控制外界修改客户信息的行为以保护客户信息。



二、类图


代理模式(Proxy Pattern)(三):HeadFirst使用java API创建一个保护代理_第1张图片



三、代码实现


1.PersonBean,即代理模式中的抽象角色,java动态代理只能实现对interface的代理

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); 
 
}

2.PersonBeanImpl,真实角色

public class PersonBeanImpl implements PersonBean
{
	String name;
	String gender;
	String interests;
	int rating;
	int ratingCount = 0;

	public String getName()
	{
		return name;
	}

	public String getGender()
	{
		return gender;
	}

	public String getInterests()
	{
		return interests;
	}

	public int getHotOrNotRating()
	{
		if (ratingCount == 0)
			return 0;
		return (rating / ratingCount);
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public void setGender(String gender)
	{
		this.gender = gender;
	}

	public void setInterests(String interests)
	{
		this.interests = interests;
	}

	public void setHotOrNotRating(int rating)
	{
		this.rating += rating;
		ratingCount++;
	}
}

3.NonOwnerInvocationHandler,自定义的调用处理器,负责控制其他人修改客户信息

public class NonOwnerInvocationHandler implements InvocationHandler
{
	PersonBean person;

	public NonOwnerInvocationHandler(PersonBean person)
	{
		this.person = person;
	}

	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;
	}
}

4.OwnerInvocationHandler,自定义的调用处理器,负责控制客户自己修改自己的信息。

public class OwnerInvocationHandler implements InvocationHandler
{
	PersonBean person;

	public OwnerInvocationHandler(PersonBean person)
	{
		this.person = person;
	}

	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;
	}
}

5.简单测试

public class Test
{
	public static void main(String[] args)
	{
	  PersonBean person=new PersonBeanImpl();
	  InvocationHandler h1=new NonOwnerInvocationHandler(person);
	  InvocationHandler h2=new OwnerInvocationHandler(person);

	  Class[] interfaces= person.getClass().getInterfaces();
	  ClassLoader loader=h1.getClass().getClassLoader();

	  PersonBean noOwner=(PersonBean)java.lang.reflect.Proxy.newProxyInstance(loader,interfaces, h1);
	  PersonBean Owner=(PersonBean)java.lang.reflect.Proxy.newProxyInstance(loader,interfaces, h2);
      
      //简单测试对set方法的调用权限
	  noOwner.setHotOrNotRating(4);
	  Owner.setName("heihei");
	  System.out.println(person.getName()+" "+person.getHotOrNotRating());
	  System.out.println("-----------------");
	  noOwner.setName("haha");//抛异常
	  Owner.setHotOrNotRating(3);//抛异常

	}
}

在这里,写了两个调用处理器,一个是处理其他人对personBean方法的访问,一个是处理自己对PersonBean方法的访问,主要是控制对set方法的调用以达到保护客户信息的目的,重点是invoke()方法的编写。



转载请注明出处:http://blog.csdn.net/jialinqiang/article/details/8973749

你可能感兴趣的:(java,设计模式,proxy,Headfirst)