headFirst学习笔记之十一:代理模式之三保护代理(5.2)

1.动态代理:java在java.lang.reflect包中有自己的代理支持,利用这个包你可以在运行时动态的创建一个代理类,实现一个或者多个接口,并且将方法的调用转发到你指定的类。

保护代理:根据访问权限决定客户可否访问对象的代理。

2.任务:对象村的小伙伴们要相亲啦~请负责帮忙实现约会服务系统。

(1)PersonBean接口,允许设置或获取一个人的信息等。

 1 public interface PersonBean {
 2     public String getName() ;
 3     public void setName(String name) ;
 4     public String getGender() ;
 5     public void setGender(String gender);
 6     public String getInterests();
 7     public void setInterests(String interests) ;
 8     public int getHotOrNotRating();
 9     public void setHotOrNotRating(int hotOrNotRating);
10 }

(2)实例化personBean。

 1 public class PersonBeanImpl implements PersonBean {
 2     String name;
 3     String gender;
 4     String interests;
 5     int rating;//总分数
 6     int ratingCount=0;//评分次数
 7     public String getName() {
 8         return name;
 9     }
10     public void setName(String name) {
11         this.name = name;
12     }
13     public String getGender() {
14         return gender;
15     }
16     public void setGender(String gender) {
17         this.gender = gender;
18     }
19     public String getInterests() {
20         return interests;
21     }
22     public void setInterests(String interests) {
23         this.interests = interests;
24     }
25     public int getRating() {
26         return rating;
27     }
28     public void setHotOrNotRating(int rating) {
29         this.rating += rating;
30         ratingCount++;
31     }
32     public int getHotOrNotRating() {
33         if(ratingCount==0){
34             return 0;
35         }else{
36             return (rating/ratingCount);
37         }
38     }
39 }

那么问题来了:根据我们定义的方式,任何客户都可以调用任何方法。每个方法的返回信息都是公开的。但是在我们的相亲系统中,希望用户可以设置自己的信息,同时能防止别人修改。并且自己不能给自己打分,只能别人打分。

解决办法:必须创建两个代理,一个访问自己的PersonBean,一个访问别人的PersonBean,这样代理就可以控制在每一种情况下,允许哪一种请求。

3.动态代理创建

(1)创建InvocationHandler

InvocationHandler是调用处理器,当proxy的方法setName()被调用时,就会调用InvocationHandler的invoke()方法,然后handler来决定如何处理这个请求,可能是发给realSubject。因为有两个代理,所以要创建两个InvocationHandler。

 1 import java.lang.reflect.*;
 2
 3 public class OwnerInvocationHandler implements InvocationHandler {
 4     PersonBean personBean;
 5
 6     public OwnerInvocationHandler(PersonBean personBean) {
 7         super();
 8         this.personBean = personBean;
 9     }
10
11
12     public Object invoke(Object proxy, Method method, Object[] args)
13             throws IllegalAccessException {
14
15         try {
16             //唯独不能给自己打分
17             if(method.getName().equals("setHotOrNotRating")){
18                 throw new IllegalAccessException();
19             }
20             else if(method.getName().startsWith("get")){
21                 //只要是get都可以
22                 return method.invoke(personBean, args);
23             }
24         } catch (InvocationTargetException e) {
25             e.printStackTrace();
26         }
27
28         return null;
29     }
30
31 }

 1 import java.lang.reflect.*;
 2
 3 public class NonOwnerInvocationHandler implements InvocationHandler {
 4     PersonBean personBean;
 5
 6     public NonOwnerInvocationHandler(PersonBean personBean) {
 7         super();
 8         this.personBean = personBean;
 9     }
10
11
12     public Object invoke(Object proxy, Method method, Object[] args)
13             throws IllegalAccessException {
14
15         try {
16             //get都可以
17             if(method.getName().startsWith("get")){
18                 return method.invoke(personBean, args);
19             }
20             //set只能是打分
21             else if(method.getName().equals("setHotOrNotRating")){
22                 return method.invoke(personBean, args);
23             }
24             else if(method.getName().startsWith("set")){
25                 //如果是其他set
26                 throw new IllegalAccessException();
27             }
28         } catch (InvocationTargetException e) {
29             e.printStackTrace();
30         }
31
32         return null;
33     }
34
35 }

(2)写代码创建动态代理

(3)利用适当的代理包装任何PersonBean对象。

to be continued

时间: 2024-09-28 11:10:18

headFirst学习笔记之十一:代理模式之三保护代理(5.2)的相关文章

headFirst学习笔记之十一:代理模式(5.2)

1.目前任务: 上一章的万能糖果机的CEO,希望我们能发给它一份库存以及机器状态的报告.(简直就是小cese,CEO一定会被我的编码能力折服的hiahiahia~) (1)在上一章的代码中加入location变量(2)然后添加糖果机监视器这个类.有一个问题:我点击运行后控制台什么反应都没有,我也不能输入信息.这是什么情况? 1 public class GumballMachine { 2 String location; 3 int count = 0; 4 public GumballMac

headFirst学习笔记之六:命令模式(4.30)

1.要完成的任务: 目标:设计一个家电自动化遥控器的API,让每个插槽都能控制一个或者一组装置.能够控制目前的装置和任何未来可能出现的装置这一点非常重要. 已知条件: (1)这个遥控器有7个可编程的插槽(每个都可以指定到一个不同的家电装置),每个插槽都有对应的开关按钮.这个遥控器还具备一个整体的撤销按钮. (2)提供一个光盘,里面是厂商类,用来控制家电自动化装置,比如电灯.风扇.热水器等可控制装置.部分如下所示,类不少,接口也各有差异. 1 class TV{ 2 on(){} 3 off(){

马哥学习笔记二十一——LVS DR模型

kernel parameter: arp_ignore: 定义接收到ARP请求时的响应级别: 0:只要本地配置的有相应地址,就给予响应: 1:仅在请求的目标地址配置请求到达的接口上的时候,才给予响应: arp_announce:定义将自己地址向外通告时的通告级别: 0:将本地任何接口上的任何地址向外通告: 1:试图仅向目标网络通告与其网络匹配的地址: 2:仅向与本地接口上地址匹配的网络进行通告: curl命令选项: --cacert <file> CA证书 (SSL) --capath &l

《Javascript权威指南》学习笔记之十一:处理字符串---String类和正则表达式

一.正则表达式的基本语法 1.概念:正则表达式由普通字符和特殊字符(元字符)组成的文本模式,该模式描述在查找字符串主体时待匹配的一个或者多个字符串.正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配. 普通字符包括所有的大小写字母字符.所有数字.所有标点符号及一些特殊符号.普通字符本身可以组成一个正则表达式,也可以和元字符组合组成一个正则表达式:而元字符则具有特殊的含义,包括().[].{}./.^.$.*.+.?...|.-.?:.?=.?! 2.基本语法 3.优先权含义 二.使用

VSTO 学习笔记(十一)开发Excel 2010 64位自定义公式

原文:VSTO 学习笔记(十一)开发Excel 2010 64位自定义公式 Excel包含很多公式,如数学.日期.文本.逻辑等公式,非常方便,可以灵活快捷的对数据进行处理,达到我们想要的效果.Excel的内置公式虽然强大,但是在ERP等系统中,往往需要进行很多业务上的计算,如收发存台账.指定年.月.部门的消耗查询等,都是需要从数据库中查询的,且和业务紧密相连.这时仅仅依靠Excel的内置公式就不够了,需要添加自定义的公式来进行这些业务计算. 测试代码下载 本系列所有测试代码均在Visual St

angular学习笔记(三十一)-$location(2)

之前已经介绍了$location服务的基本用法:angular学习笔记(三十一)-$location(1). 这篇是上一篇的进阶,介绍$location的配置,兼容各版本浏览器,等. *注意,这里介绍的是基于angular-1.3.2版本的,低版本的$location可能会有问题. hashbang模式和history api创建单页应用 首先,$location是用在单页应用里的...(废话,angular就是用在单页的)...所以,$location处理的是url改变,但是不刷新页面的情况.

【Unity 3D】学习笔记三十一:游戏元素——地形元素

地形元素 一般情况下,为了使游戏更具有美观性,会在游戏地形上放置很多的元素,这些元素是与地形分开的.主要包括:树木,草地,自定义网格模型. 树元素 首先导入系统提供的树木标准资源包,在project视图中,点击鼠标右键,然后从菜单中选择import-----tree creator.接着在地形菜单里点击第五个按钮,添加树模型.然后点击edit trees按钮,将弹出如下列表: add tree:添加一个树模型 edit tree:编辑一个树模型 remove tree:删除树模型 点击add t

o&#39;Reill的SVG精髓(第二版)学习笔记——第十一章

第十一章:滤镜 11.1滤镜的工作原理 当SVG阅读器程序处理一个图形对象时,它会将对象呈现在位图输出设备上:在某一时刻,阅读器程序会把对象的描述信息转换为一组对应的像素,然后呈现在输出设备上.例如我们用SVG的<filter>元素指定一组操作(也称作基元,primitive),在对象的旁边显示一个模糊的投影,然后把这个滤镜附加给一个对象: <fliter id="drop-shadow"> <!-- 这是滤镜操作 --> </fliter&g

Android学习笔记(十一)——从意图返回结果

从意图返回结果 startActivity()方法调用另一个活动,但并没有返回结果给当前活动.此时如想从一个活动中回传数据,就要使用startActivityForResult()方法. 点此获取完整代码~                                                                  1.使用上一篇中创建的项目,在secondactivity.xml文件中添加文本框和按钮,代码如下: <TextView android:layout_width