- 浏览: 341330 次
- 性别:
- 来自: 广州
文章分类
最新评论
本章所述是来自真实的华尔款街金融网站项目,在本站要实现两个基本功能:一是必须对用户进行身份检查,二是对用户搜索次数进行统计,以便按照收费标准进行收费.在这里要用到两种模式:保护代理和智能代理。一个代理对象对调用被代理对象的用户进行权限检查,并且只允许有适当权限的用户调用原对象,这样的代理对象叫做保护代理。所谓智能引用代理,就是一个代理对象对调用原对象的用户进行统计计数.
一:系统设计步骤
(A)抽象和具体的划分
首先,系统需要一个能进行查询的类,但是有经验的设计师不会仅仅给出一个具体类就交差,因为设计师必须考虑到查询功能在今后可能会有变化,因此一个好的设计师必须使系统可以在最小的改动下进行最大的扩充.所以应当有一个抽象和一个具体角色,抽象角色给出接口的声明,而将实现的细节交给具体的角色.这样如果在将来需要有新的查询功能,只需要创建一个新的具体角色就好了,而无需改变抽象角色.我们这里抽象角色由Java的接口(Searcher)扮演,个体角色由一个类(RealSearcher)扮演.
(B)辅助功能的提供
当然,系统必须有两个辅助对象,一个用于检查用户权限,为AccessValidator,另一个用做查询的计数器,为UsageLogger。这两个辅助对象分别提供适当的方法检查用户的权限和将查询事件记录到数据库中。一般而言,稍有经验的设计师都会想到使用独立的对象负责这两项责任,而不是由负责查询的Searcher或者RealSearcher负责所有的责任.
(C)引入代理角色
基本的功能现在都有确定的对象提供了:查询功能由RealSearch对象提供,检查用户权限的功能由AccessValidator提供,记录查询次数的功能由UsageLogger对象提供.
一个没有代理模式知识和应用代理模式的设计师往往就在这里停下来了,因为人们往往会认为只要修改一下RealSearcher对象的方法,在查询操作之前进行权限的检查,在查询之后进行查询次数的记录就可以了。当然是可以的,只是不够好,为什么?因为对权限的检查和记录调用次数的责任属于RealSearcher对象的调用控制,这个责任应当与RealSearcher对象本身分开.换言之,系统应当对RealSearcher对象提供一个代理对象,由代理对象负责这两项工作,并将调用委派给RealSearcher对象.代理对象Proxy持有RealSearcher对象,AccessValidator对象和UsageLogger对象的引用.
二:系统的时序
(A)客户端调用代理对象
(B)代理对象调用AccessValidator对象,确定用户确实具有的相应的权限
(C)代理对象调用RealSearcher对象,完成查询功能
(D)代理对象调用UsageLogger对象,完成计数功能
(E)代理对象将RealSearcher对象的查询结果返回给客户端
源代码如下:
一:系统设计步骤
(A)抽象和具体的划分
首先,系统需要一个能进行查询的类,但是有经验的设计师不会仅仅给出一个具体类就交差,因为设计师必须考虑到查询功能在今后可能会有变化,因此一个好的设计师必须使系统可以在最小的改动下进行最大的扩充.所以应当有一个抽象和一个具体角色,抽象角色给出接口的声明,而将实现的细节交给具体的角色.这样如果在将来需要有新的查询功能,只需要创建一个新的具体角色就好了,而无需改变抽象角色.我们这里抽象角色由Java的接口(Searcher)扮演,个体角色由一个类(RealSearcher)扮演.
(B)辅助功能的提供
当然,系统必须有两个辅助对象,一个用于检查用户权限,为AccessValidator,另一个用做查询的计数器,为UsageLogger。这两个辅助对象分别提供适当的方法检查用户的权限和将查询事件记录到数据库中。一般而言,稍有经验的设计师都会想到使用独立的对象负责这两项责任,而不是由负责查询的Searcher或者RealSearcher负责所有的责任.
(C)引入代理角色
基本的功能现在都有确定的对象提供了:查询功能由RealSearch对象提供,检查用户权限的功能由AccessValidator提供,记录查询次数的功能由UsageLogger对象提供.
一个没有代理模式知识和应用代理模式的设计师往往就在这里停下来了,因为人们往往会认为只要修改一下RealSearcher对象的方法,在查询操作之前进行权限的检查,在查询之后进行查询次数的记录就可以了。当然是可以的,只是不够好,为什么?因为对权限的检查和记录调用次数的责任属于RealSearcher对象的调用控制,这个责任应当与RealSearcher对象本身分开.换言之,系统应当对RealSearcher对象提供一个代理对象,由代理对象负责这两项工作,并将调用委派给RealSearcher对象.代理对象Proxy持有RealSearcher对象,AccessValidator对象和UsageLogger对象的引用.
二:系统的时序
(A)客户端调用代理对象
(B)代理对象调用AccessValidator对象,确定用户确实具有的相应的权限
(C)代理对象调用RealSearcher对象,完成查询功能
(D)代理对象调用UsageLogger对象,完成计数功能
(E)代理对象将RealSearcher对象的查询结果返回给客户端
源代码如下:
package cai.milenfan.basic.test; public interface Searcher { String doSearch(String userId,String keyValue); }
package cai.milenfan.basic.test; public class RealSearcher implements Searcher{ //真实的查询工作在这里 public String doSearch(String userId, String searchType) { String sql = "select * from table"; //execute.... return "result"; } }
package cai.milenfan.basic.test; public class Proxy implements Searcher{ private RealSearcher searcher; private UsageLogger usageLogger; private AccessValidator accessValidator; public Proxy(){ searcher = new RealSearcher(); } public String doSearch(String userId,String keyValue){ if(checkAccess(userId)){ String result = searcher.doSearch(null, keyValue); logUsage(userId); return result; }else{ return null; } } //查询前的权限操作 private boolean checkAccess(String userId){ accessValidator = new AccessValidator(); return accessValidator.vaidateUser(userId); } //查询后的日志操作 private void logUsage(String userId){ UsageLogger logger = new UsageLogger(); logger.setUserId(userId); logger.save(); } }
package cai.milenfan.basic.test; public class AccessValidator { public boolean vaidateUser(String userId){ if(userId.equals("admin")){ return true; }else{ return false; } } }
package cai.milenfan.basic.test; public class UsageLogger { private String userId; public void setUserId(String userId){ this.userId = userId; } //将这次使用记录加到日志中 public void save(){ String sql = "insert into table"; //execute.. } public void save(String userId){ this.userId = userId; save(); } }
package cai.milenfan.basic.test; public class Client { //申明一个静态变量searcher private static Searcher searcher; public static void main(String[] args){ //此变量的真实类型为Proxy,这就保证了客户端不能分辨RealSearcher和Proxy,这是代理模式的用意之一 searcher = new Proxy(); String userId="Admin"; String searchType="SEARCH_BY_ACCOUNT_NUMBER"; String result = searcher.doSearch(userId,searchType); System.out.println(result); } }
发表评论
-
Mina重连
2014-05-26 21:29 2927import com.sun.swing.internal. ... -
面试经典
2014-05-24 09:29 6431.mysql innodb引擎,什么叫聚集索引,与非聚集索 ... -
一拍网网站系统架构图
2014-03-28 21:24 623一拍网网站系统架构图 -
Window下安装配置nginx
2013-08-12 16:53 809安装:http://www.cnblogs.com/wen ... -
使用线程池的好处
2013-07-18 14:41 1252使用线程池有两个好处: 1.可以创建和销毁线程所带来的系统 ... -
Java ThreadLocal使用浅析
2013-07-18 14:36 483ThreadLocal通过在其内部保存变量的副本,并且各个副本 ... -
MyBatis学习之简单增删改查操作、MyBatis存储过程、MyBatis分页、MyBatis一对一、MyBatis一对多
2013-07-05 13:06 1177http://blog.csdn.net/zhangwei ... -
分享一位网友的架构杂谈
2013-05-20 23:16 913不容类型的网站,并发处理不一样,例如针对sns这种类型的网站 ... -
JSP页面静态化
2013-04-08 09:20 890http://www.java-zone.org/644.ht ... -
Java compile to C++
2013-03-19 14:53 507http://code.google.com/a/eclips ... -
几个TCP Socket的通信框架
2013-03-19 12:26 996http://www.oschina.net/p/simple ... -
宝贝鱼
2013-03-18 23:54 692http://code.google.com/p/cshbbr ... -
将Java程序注册成系统服务(NT服务)
2013-03-16 16:14 604http://blog.csdn.net/small____f ... -
Java内存回收机制
2013-03-13 15:47 814http://www.iteye.com/blogs/tag/ ... -
支付宝,百付宝集成
2013-03-13 14:01 975http://help.alipay.com/support/ ... -
SSH+EXTJS项目下载
2013-03-11 23:02 437http://download.csdn.net/tag/Ex ... -
Hibernate中使用Threadlocal创建线程安全的Session
2013-03-04 20:39 592http://blog.sina.com.cn/s/blog_ ... -
Java Socket多线程通信
2012-10-09 09:53 839当Server没接受到一个Client连接请求之后,都把处理流 ... -
Java 多线程的一个例子
2012-10-09 09:48 1024目录: 1 synchronized的 ... -
app引擎
2012-07-10 09:39 0http://sae.sina.com.cn/ htt ...
相关推荐
*智能引用代理:在智能引用代理中,使用代理对象来智能地管理被代理对象的生命周期。 代理模式是一种非常重要的设计模式,它可以帮助我们控制对对象的访问,保护对象不被外部访问,并提供一个灵活的方式来扩展对象...
1. **代理的类型**:代理模型通常分为多种类型,包括虚拟代理(用于延迟加载或缓存)、远程代理(处理网络通信)、保护代理(控制对原始对象的访问权限)和智能引用代理(提供额外的元数据或操作)等。每种类型的...
5. **智能引用代理**:除了保持对目标对象的引用,还可以提供一些额外的信息,如引用计数。 在实际应用中,苹果的UIKit框架广泛使用了代理模式,如UITableViewDataSource和UITableViewDelegate,以及UIWebView的...
- **智能引用代理**:提供额外的逻辑,比如增加引用计数,防止对象过早释放。 3. **在iOS中的应用**: - **UITableView/UICollectionView的数据源代理**:负责填充表格或集合视图的数据,如`...
8. **智能引用代理**:在对象被引用时执行附加操作,例如计数引用次数或执行清理任务。 代理模式的使用可以使系统更加灵活,能够添加新的功能或控制,同时保持原有对象的简洁性。在软件设计中,尤其是在大型系统中...
5. **智能引用代理**:当真实对象的生命周期依赖于代理时,可以使用智能引用代理。智能引用代理可以跟踪真实对象的状态,并确保当不再需要时,真实对象被正确地销毁。 #### 四、代理模式的优点 - **增强功能**:...
- **智能引用代理**:除了保持目标对象的引用,还可以记录对象的状态、计数引用次数等。 在实际编程中,代理模式的实现可以分为静态代理和动态代理两种方式: 1. **静态代理**:在编译时就已经确定了代理类,需要...
5. **智能引用(Smart Reference)**:在垃圾回收机制中,智能引用代理可以在对象被引用时执行一些操作,如计数、资源释放等。 在代理模式的实现中,通常会使用到面向对象的特性,如继承、多态和接口。代理对象可以...
8. 智能引用代理:当一个对象被引用时,提供一些额外的操作,如将此对象被调用的次数记录下来等。 代理模式与适配器模式的区别在于,代理模式面对相同的接口,而适配器模式面对不同的接口。代理模式提供了一个对象...
- 智能引用代理:当一个对象被引用时,提供一些额外的操作,比如跟踪引用这个对象的次数。 #### 四、装饰模式简介 装饰模式是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。这种...
4. 智能引用代理:可以添加一些额外的操作,比如引用计数、对象访问计数、对象创建日志记录等。 代理模式的适用场景包括: - 当客户不想或者不适合直接引用一个对象,或是访问一个对象存在困难时,可以使用代理模式...
- **智能引用代理**: 实现额外的功能,如跟踪引用次数。 #### 三、动态代理 动态代理是指在运行时动态创建代理对象的过程。Java提供了`java.lang.reflect.Proxy`类和`InvocationHandler`接口来支持动态代理。 ###...
8. **智能引用代理(Smart Reference Proxy)**:在对象被引用时执行额外操作,例如统计引用次数或执行资源管理。 以Java动态代理实现为例,`ReflectProxy`类实现了`InvocationHandler`接口,并通过`factory()`方法...
4. **智能引用代理**:当对象被引用时,提供一些额外的操作或检查。 总之,代理模式作为一种常见的设计模式,能够有效地帮助我们在不改变原有代码的基础上增加额外的功能,提高代码的复用性和灵活性。通过合理选择...
4. **智能引用代理**:除了简单的引用之外,还可以提供额外的功能,如缓存、日志记录、计数等。这样可以在不影响原有接口的前提下,增加系统的功能和监控能力。 代理模式的实现方式主要有两种: **静态代理**:如...
5. **智能引用代理(Smart Reference Proxy)**:提供一些额外的管理功能,例如计数引用次数,以便在引用计数为零时自动释放对象。 **代码实现:** 在C#中,代理模式可以通过实现同一接口来实现。下面是一个简单的...
5. **智能引用代理**:除了存储对原始对象的引用外,还可能提供额外的信息或操作,如计数器来记录对象的使用次数。 标签“源码”和“工具”暗示了这篇博客可能涉及了具体的代码实现和实用性工具。在实际的编程语言...
其次,代理模式也被应用于收费商务信息查询系统的身份验证和日志记录,通过保护代理和智能引用代理,我们可以以松耦合的方式向系统添加新功能,同时保持客户端代码的一致性。 2. **职责链模式**: 职责链模式是一种...
其他代理模式还有保护代理、缓存代理、同步代理、智能引用代理和复杂隐藏代理等。 工厂模式(Factory Pattern)是一种创建型设计模式,用于创建对象而无需指定将要创建的对象的确切类。工厂模式是类的创建者和使用...