代理模式小试

一、介绍

什么是代理模式。

惯例,我们先看一下《研磨设计模式》中的介绍——为其他对象提供一种代理以控制对这个对象的访问。代理模式的本质是——控制对象访问

什么意思呢?

就是我们每次访问一个对象的时候,实际上去访问这个对象的代理。这个代理实际上就是这个对象的替身,可以实现原本对象绝大多数的功能。只有当需要某些特殊功能的时候,才去调用原本的对象。这样一来,在不修改原对象的情况下,就可以在代理对象上实现很多特殊的功能。这些功能基本都属于访问控制。

这里所说的代理跟我们平时所说的各种代理,其实就是一个意思。所以说,像JDK动态代理、CGLib动态代理这些也都是代理模式的一个体现。

关于JDK动态代理和CGLib动态代理的简单演示可以参考一下我的另一篇博文JDK动态代理和CGLib动态代理简单演示

二、我的实现

假设我们有一个user表,对应一个实体类User。它有一个字段是passward。现在我们需要控制这个字段的访问权限,只有它本人才能查看和修改,管理员也只能查看,不能修改。

一般可以采用接口的设计,让代理类和被代理类都实现同一个接口,但是,这里演示为了减少耦合,就不这么做了。如下:

1、很简单的实体类:


 1 public class User {
2
3 private String userId;
4 private String userName;
5 private String password;
6
7 public User(String userId, String userName, String password) {
8 super();
9 this.userId = userId;
10 this.userName = userName;
11 this.password = password;
12 }
13
14 public String getUserId() {
15 return userId;
16 }
17
18 public void setUserId(String userId) {
19 this.userId = userId;
20 }
21
22 public String getUserName() {
23 return userName;
24 }
25
26 public void setUserName(String userName) {
27 this.userName = userName;
28 }
29
30 public String getPassword() {
31 return password;
32 }
33
34 public void setPassword(String password) {
35 this.password = password;
36 }
37
38 }

2、很简单的代理类:


 1 public class UserProxy {
2
3 User user = null;
4
5 UserProxy(User user) {
6 this.user = user;
7 }
8
9 public String getUserId() {
10 return user.getUserId();
11 }
12
13 public void setUserId(String userId) {
14 user.setUserId(userId);
15 }
16
17 public String getUserName() {
18 return user.getUserName();
19 }
20
21 public void setUserName(String userName) {
22 user.setUserName(userName);
23 }
24
25 // 查看密码做权限控制
26 public String getPassword() {
27 // 判断是否为用户本身,或管理员
28 if (isSelf() || isManager()) {
29 return user.getPassword();
30 } else {
31 System.out.println("对不起," + user.getUserName() + ",您没有足够的权限!");
32 return null;
33 }
34 }
35
36 // 修改密码做权限控制
37 public void setPassword(String password) {
38 // 判断是否为用户本身
39 if (isSelf()) {
40 user.setPassword(password);
41 } else {
42 System.out.println("对不起," + user.getUserName() + ",您没有足够的权限!");
43 }
44 }
45
46 // 权限判断,是否为用户自身
47 private boolean isSelf() {
48 // 一般可以在session中当前用户id,比较。
49 // 这里假设不是用户自身
50 return false;
51 }
52
53 // 权限判断,是否为管理员
54 private boolean isManager() {
55 // 一般可以在session中当前用户id,比较。
56 // 这里假设是管理员
57 return true;
58 }
59 }

3、我们测试一下:


 1 public class Test {
2
3 public static void main(String[] args) {
4 User user = new User("001", "张三", "12345");
5 UserProxy proxy = new UserProxy(user);
6 System.out.println("用户名:" + proxy.getUserName());
7 System.out.println("现在查看密码!");
8 System.out.println("用户密码:" + proxy.getPassword());
9 System.out.println("现在修改密码!");
10 proxy.setPassword("54321");
11 }
12 }

如上,实现了简单的权限控制了。

三、虚代理

代理有很多种,如虚代理、远程代理、copy-on-write、保护代理、Cache代理、防火墙代理、同步代理、智能代理等等。

需要仔细了解,可以自行查找相关资料。

不过万变不离其宗,这些代理都是符合代理模式的思想的。

上面我的实现,演示的是保护代理。这里再简要介绍一下虚代理。

什么是虚代理呢?对于创建开销很大的对象,用一个创建开销较小的代理对象代替,一般情况下,这个代理对象足够应付绝大多数用户请求。只有当用户请求原对象的特殊功能时,才会创建原对象。

《研磨设计模式》介绍了一种很常用的实现:

一个数据表有很多字段,通常只需要显示其中几个字段,这种情况下就需要使用虚代理来进行优化了。如下:

1、这里用一个接口来统筹目标对象和代理对象,只有简单的get/set方法,如下:


 1 public interface UserModelApi {
2
3 public String getUserId();
4
5 public void setUserId();
6
7 public String getUserName();
8
9 public void setUserName();
10
11 public String getPassname();
12
13 public void setPassname();
14
15 }

2、目标类这里就不列出了,代理类如下:


 1 public class MyProxy implements UserModelApi {
2
3 // 数据库初次查询后得到的对象,只有一部分字段。
4 private UserModelApi object = null;
5
6 // 标记是否被加载过,即是否深入查询过。
7 private boolean loaded = false;
8
9 public MyProxy(UserModelApi object) {
10 this.object = object;
11 }
12
13 @Override
14 public String getUserId() {
15 return object.getUserId();
16 }
17
18 @Override
19 public String getUserName() {
20 return object.getUserName();
21 }
22
23 @Override
24 public void setUserId(String userId) {
25 object.setUserId(userId);
26 }
27
28 @Override
29 public void setUserName(String userName) {
30 object.setUserName(userName);
31 }
32
33 @Override
34 public void setPassword(String password) {
35 // 设置属性和查询不同,需要另外的
36 object.setPassword(password);
37 }
38
39 @Override
40 // 这里,当请求得到password的时候,由于传入的UserModelApi对象并未包含这个字段
41 // 所以需要深入查询。
42 public String getPassword() {
43 // 需要判断是否已经装载过了
44 if (!this.loaded) {
45 reload();
46 this.loaded = true;
47 }
48 return object.getPassword();
49 }
50
51 private void reload(){
52 //查询数据库,注入字段到object对象
53 }
54 }

------------------------------------------------------------------------------------------------------------------------------------------------------------

PS:如果本篇博文您觉得不错的话,请别忘了推荐一下,谢谢。

代理模式小试,布布扣,bubuko.com

时间: 2024-10-17 15:41:34

代理模式小试的相关文章

Spring框架_代理模式(静态代理,动态代理,cglib代理)

共性问题: 1. 服务器启动报错,什么原因? * jar包缺少.jar包冲突 1) 先检查项目中是否缺少jar包引用 2) 服务器: 检查jar包有没有发布到服务器下:                                      用户库jar包,需要手动发布到tomcat. (每次新建项目) 3) 重新发布项目 * 配置文件错误 (web.xml / struts.xml /bean.xml /hibernate.xml / *.hbm.xml) 明确的提示 * 端口占用 * we

拦截器的设计思想——代理模式

代理模式:静态代理和动态代理 1.代理类和被代理类必须实现同一个借口 2.代理类和别代理类有一种关联关系 静态代理: 例如实现一个日志: //定义一个接口 public interface UserDao{ public void delete(); } //定义一个实现类 public class UserDaoImpl implements UserDao{ public void delete(){ System.out.pritln("成功删除"); } } //定义一个代理类

Java设计模式——代理模式

前言: 上一篇说到了策略模式.单类图上来说,它和本篇要说的代理模式还真是有些像似.都需要一个公共的接口,还有一些实现类.代理类(包装类)封装了一个接口对象,提供客户端调用.这些都很类似.不过,有一个细节需要我们注意一下,那就是这里的代理类也需要去继承这里的公共接口.而在策略模式中,包装类则不需要这么做. 概述: 代理模式就是定义一个原对象的代理对象,来帮助原对象和系统之外的业务作沟通.也就是说,如果我们不能直接或是不愿直接去使用原对象,那么我们就可以使用创建一个原对象的代理来进行操作. 本文链接

代理模式(Proxy)

代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问. 在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 代理模式一般涉及到的角色有 抽象角色:声明真实对象和代理对象的共工接口 代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象.同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装. 真实角色:代理角色所代表的真实对

深刻理解代理模式在java中如何优化系统性能

最近参与实习公司的项目迭代,项目中需要实现系统的快速响应和大量数据处理.在不断的学习中获得一点儿心得,先记录下来.慢慢的修改! 关于代理模式的知识和简单应用之前的学习笔记中已经有记录了,可以复习一下.这里主要记录如何使用代理模式来实现延迟加载,进而提升系统系能和反应速度. 使用代理模式实现延迟加载的一个简单实例: 需求:项目中对系统的启动速度做了一定的要求 我们在系统首次加载时,因为不需要实际的数据来构造显示界面,这就为我们实现系统首次加载的快速响应提供了可能.在常规模式下,我们一般会在系统启动

使用反射机制调用属性和私有成员与代理模式的介绍

使用反射机制调用属性: 通过反射机制可以获得类的属性,获得到的属性同样的可以进行赋值.得值操作,调用getField方法并传递属性的名称可以获得[学Java,到凯哥学堂kaige123.com]指定的属性,调用getFields方法则可以获得全部属性,但是这种方式不能获得私有属性: 代码示例: Student类示例: 运行结果: 从运行结果可以看出只拿出了公开的属性,私有的属性拿不到. 使用反射机制调用私有成员: 1.调用私有属性 在反射机制里调用私有属性需要通过getDeclaredField

动态代理模式

动态代理模式简介: 动态代理能够自动监听代理对象的方法,并且能够自动生成代理类的代码,这样就不需要我们自己去重写代理对象里的方法了,这样解决了代理类代码因业务庞大而庞大的问题,因为动态代理模式会在代码运行时根据代码来在内存中动态生成一个代理类自动重写代理对象[学Java,到凯哥学堂kaige123.com]的方法,然后这个动态代理类再调用处理类里的代码,处理类再调用到实际方法上去.而且我们可以选择性的监听代理对象的方法,有些不需监听的方法就可以在处理类中过滤掉.所以动态代理的优势就在于可以自动的

设计模式(十四):代理模式

一.概述 代理模式为另一个对象提供一个替身或占位符以控制对这个对象的访问.其实就是代理就是做到类似转发的功能,针对不同代理,转发的具体实现不同. 二.解决问题 从原理知道他就是控制客户对一个对象的访问,它跟现实中的中介代理类似,只是作为代表做一些受理工作,真正执行的并不是它自己.比如买火车票,外面有很多火车票代理点,我们直接去代理点买票就好而不用跑到火车票买了(暂时不考虑网购哈). 三.结构类图 四.应用实例 在这个例子中,主要讲解远程代理,它可以作为另一个JVM上的本地代表.客户端调用代理的方

设计模式之代理模式

代理模式(Proxy)为其他对象提供一种代理以控制对这个对象的访问.使用场合,第一,远程代理,也就是为一个对象在不同的地址空间提供局部代表.这样可以隐藏一个对象存在于不同地址空间的事实:第二,虚拟代理,是根据需要创建开销很大的对象.通过它来存在实例化需要很长时间的真实对象:第三,安全代理,用来控制真实对象访问时的权限:第四,智能指引,是指当调用真实的对象时,代理处理另外一些事情.代理模式与外观模式有点像,但外观模式中外观与实体不一定具备相同的接口,两者都在一定程度上隐藏了系统的复杂性. 代理模式