代理模式的类图如下所示:

客户端想调用的是RealSubject,由于某种考虑或原因,只能直接访问到ProxySubject,再由ProxySubject去调用RealSubject,这就完成了一次代理的活动。

代理模式的时序图如下:

从上面可以看出,ProxySubject不仅可以完成对RealSubject的调用,在调用前后还可以完成一些事情,这就是代理模式的优点。

代理模式按照使用的分类,可以分为以下几类:

远程代理:为一个不同地址空间的对象提供一个局域代表对象。

虚拟代理:根据需求创建一个资源消耗较大的对象,使得对象在使用时才被真正地使用。

Copy-on-Write代理:虚拟代理的一种,把复制行为推迟到真正需要时再去执行。

保护代理:控制对一个对象的访问,可以对不同用户提供不同权限。

Cache代理:为某一目标的操作结果提供临时的存储空间,使得多个客户端可以共享这些结果。

同步化代理:使得多个用户同时使用一个目标而没有冲突。

智能引用代理:引用一个对象时提供一些额外的操作,如记录被调用的次数等。

Java类库中有三个类直接支持代理模式:Proxy,InvocationHandler和Method。

下面是在List加上代理,在添加元素的前后打印一些信息。

public class VectorProxy implements InvocationHandler{
private Object proxyobj;
public VectorProxy(Object obj){
proxyobj = obj;
} public static Object factory(Object obj){
Class cls = obj.getClass();
return Proxy.newProxyInstance( cls.getClassLoader(),
cls.getInterfaces(),
new VectorProxy(obj) );
} public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
System.out.println("before calling " + method); if (args != null){
for (int i=0; i<args.length; i++){
System.out.println(args[i] + "");
}
} Object o = method.invoke(proxyobj, args); System.out.println("after calling " + method); return o;
} public static void main(String[] args){
List v = null;
v = (List) factory(new Vector(10));
v.add("New");
v.add("York");
}
}

  打印出的信息如下:

before calling public abstract boolean java.util.List.add(java.lang.Object)
New
after calling public abstract boolean java.util.List.add(java.lang.Object)
before calling public abstract boolean java.util.List.add(java.lang.Object)
York
after calling public abstract boolean java.util.List.add(java.lang.Object)

  

一个网站可以为顾客提供股票的持有情况,从而判断是否是大量收购或抛售的情况,这是信息是很有用的,该网站属于计费网站。这里有两种情形是能使用代理模式的,一是对客户的身份进行检查,第二是对用户的使用情况进行统计,方便计费。

上面提到的代理模式的种类,这里就可以对应上保护代理和智能引用代理两种。

负责身份验证和查询次数记录功能类应该是分开处理,对应与上面类图中的AccessValidator和UsageLogger,统一于Proxy中进行调用。

代理类Proxy 的示例代码为:

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

  负责身份校验的AccessValidator的示例代码:

public class AccessValidator{
public boolean vaidateUser(String userId){
if (userId.equals("Admin")){
return true;
}
else{
return false;
}
}
}

  负责查询次数记录的UsageLogger的示例代码:

public class UsageLogger{
private String userId;
public void setUserId(String userId){
this.userId = userId;
} public void save(){
String sql = "INSERT INTO USAGE_TABLE (user_id) " +
" VALUES(" + userId + ")";
//execute this SQL statement
} public void save(String userId){
this.userId = userId;
save();
} }

  实际的查询处理类RealSearcher的示例代码:

class RealSearcher implements Searcher{
public RealSearcher(){
} public String doSearch(String userId, String keyValue){
String sql = "SELECT * FROM data_table WHERE key_col = '" + keyValue + "'"; //execute this SQL Statement and concatenate a result string
return "result set";
}
}

  

  系统加载一个较为耗时的模块时,首先显示“正在加载”的信息,同时在加载模块,模块加载完后去掉加载信息。这里可以使用代理模式。

加载图片时,先加载一个分辨率较低的图片,等到真正的图片加载完后再进行显示,也可以使用代理模式去实现。

代理(Proxy)模式的更多相关文章

  1. 代理(Proxy)模式简介

    Proxy 模式简介 代理模式的两个应用: 打开文档时加载大图片 例如:如果有个对象是一张很大的图片,而这张图片需要花费很长时间才能显示出来,那么当这个图片包含在文档中的后面时,使用编辑器或浏览器打开 ...

  2. 设计模式--代理(Proxy)模式

    在公司,经常性听到采购部的人说采购某样东材料,采购不了,需要通过代理商才可以.以前Insus.NET也做有一个练习<找人办事,代理设计模式(Proxy)>http://www.cnblog ...

  3. 行为模式--代理Proxy模式(Java)

    代理(AOP切面的雏形): 题记:顾名思义就是将某件事,某个东西的使用权进行为让授权转移.代理相当于中介(不同于中介者模式),在原本操作的类之间添加了一个桥梁.但代理不能去修改原有目标.比如:一个人要 ...

  4. Android与设计模式——代理(Proxy)模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描写叙述代理(Proxy)模式的: 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 代理模式 ...

  5. Java 实现代理(Proxy)模式

    类图 /** * 游戏者接口 * @author stone * */ public interface IGamePlayer { // 登录游戏 public void login(String ...

  6. 设计模式C++描述----13.代理(Proxy)模式

    一. 举例说明 我们有时打开一个网站时会发现有这样的现象,网站上的文字都显示出来了,但是上面的图片还没显示,要等一会才能显示. 这些未打开的图片的位置上,还是会有图片框和一些等待的信息的,这就是代理模 ...

  7. 十、设计模式之代理(Proxy)模式

    什么是代理模式 代理模式是对象的结构模式,为其他对象提供一种对象以控制对这个对象的访问. 代理模式的结构图如下:(源自大话设计模式)   Subject:定义了RealSubject和Proxy的公共 ...

  8. 漫谈设计模式(一):代理(Proxy)模式与适配器(Adapter)模式对比

    1.前言 为什么要将代理模式与适配器模式放在一起来说呢?因为它们有许多的共同点,当然也有一些不同的地方.首先两者都是属于结构型模式.结构型模型是这样定义的: 结构型模式涉及到如何组合类和类以获得更大的 ...

  9. Head First 设计模式 —— 13. 代理 (Proxy) 模式

    思考题 如何设计一个支持远程方法调用的系统?你要怎样才能让开发人员不用写太多代码?让远程调用看起来像本地调用一样,毫无瑕疵? P435 已经接触过 RPC 了,所以就很容易知道具体流程:客户端调用目标 ...

随机推荐

  1. [51nod1443]路径和树

    给定一幅无向带权连通图G = (V, E) (这里V是点集,E是边集).从点u开始的最短路径树是这样一幅图G1 = (V, E1),其中E1是E的子集,并且在G1中,u到所有其它点的最短路径与他在G中 ...

  2. [bzoj1273] [BeiJingWc2008]序列

    一开始想拆位..但显然没法应对进位啊什么的. 所以维护每一个长度的后缀. 查询有多少个a&2^i>0,也就是长度为(i+1)的后缀里,值为2^i...2^(i+1)-1的数有多少个. 前 ...

  3. 将简单的lambda表达式树转为对应的sqlwhere条件

    1.Lambda的介绍 园中已经有很多关于lambda的介绍了.简单来讲就是vs编译器给我带来的语法糖,本质来讲还是匿名函数.在开发中,lambda给我们带来了很多的简便.关于lambda的演变过程可 ...

  4. sql中查询同一列所有值出现的次数

    尊重原创:http://blog.csdn.net/love_java_cc/article/details/52234889 有表如下table3: 需要查询country中各个国家出现的次数 SQ ...

  5. 安装win8+Ubuntu14.04双系统的经验总结

    当时查资料,很多人推荐了easyBCD直接安装ubuntu,但是在我的笔记本上行不通.我的笔记本是Lenovo V480+win8正版系统.这是因为我的笔记本的引导结构是EFI,而不是MBR.我的方法 ...

  6. Android初学:Gradle 'HelloWorld' project refresh failed

    Gradle 'HelloWorld' project refresh failed Error:Failed to open zip file.Gradle's dependency cache m ...

  7. IDEA for Mac注册码使用

    尼玛,一不注意把磁盘抹掉了,重新下idea发现 之前的破解方法失效了 之前所有的 idea 授权服务器已遭JetBrains封杀,所以重新下载后 用之前的方法已经然并卵了,苦苦google后,发现新大 ...

  8. Tomcat配置虚拟路径访问容器外的硬盘资源

    问题: 如果tomcat中上传了很多的图片,会导致tomcat启动的时候会慢,所以应该把图片上传到tomcat容器外部 那么,问题来了: tomcat出于安全考虑,禁止了直接访问外部硬盘资源. 解决: ...

  9. Linux中ctrl+z 、ctrl+c、 ctrl+d区别

    ctrl+c,ctrl+d,ctrl+z在linux程序中意义和区别 ctrl+c和ctrl+z都是中断命令,但是他们的作用却不一样.   ctrl+c是强制中断程序的执行,,进程已经终止.   ct ...

  10. Weblogic新建域,Weblogic新建部署环境,Weblogic重新构建域

    Weblogic新建域,Weblogic新建部署环境,Weblogic重新构建域 ======================== 蕃薯耀 2018年1月29日 http://www.cnblogs. ...