天天看點

代理模式(Proxy Pattern)(三):HeadFirst使用java API建立一個保護代理一、問題描述二、類圖三、代碼實作

一、問題描述

使用java動态代理根據通路權限控制對客戶資訊的修改以保護客戶資訊,客戶的資訊包括:姓名name、性别gender、interests興趣愛好、評分HotOrNot(類似于頂或踩),這些資訊可以被所有使用者看到,隻有顧客可以修改自己的name、gender、interests,但是不能修改自己的評分,隻能由其他人給他打分。

即根據權限控制外界修改客戶資訊的行為以保護客戶資訊。

二、類圖

代理模式(Proxy Pattern)(三):HeadFirst使用java API建立一個保護代理一、問題描述二、類圖三、代碼實作

三、代碼實作

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