`
xyheqhd888
  • 浏览: 409217 次
  • 性别: Icon_minigender_1
  • 来自: 秦皇岛
社区版块
存档分类
最新评论

Proxy(代理)模式

阅读更多

Proxy(代理)模式

        普通对象所需要完成的任务是通过公共接口为外界提供自己所承诺的服务。然而,有时候合法的对象可能会因为各种原因而无法完成自己常规的任务。尤其是当对象需要很长时间才能载入内存、对象正运行在另一台计算机上或者需要获取对象消息的时候,这种情况就会频繁出现。在这种情况下,我们可以使用一个代理对象,由它来承担客户所期待的责任,并将请求转发给其背后的目标对象。

      Proxy模式的意图在于为对象提供一个代理或者占位(placeholder)来控制对该对象的访问。

 

1.  经典范例:图像代理

     代理对象通常拥有与实际对象几乎相同的接口。代理的工作方式是:把服务请求明智地转发给代理控制的底层对象,最终完成服务。避免将较大的图像加载到内存就是典型的使用Proxy模式的例子。我们假定某个应用程序中的图像属于不执行初始化显示的页面或者面板。为了避免在不需要所有图像之前载入它们,我们需要为这些图像建立代理,以便在需要时加载所请求的图像。本节提供一个图像代理例子。但是要注意,使用Proxy模式的设计有时候是非常脆弱的,这是由于它们依赖转发方法来调用其底层对象。转发可能会建立一个非常脆弱并且需要经常维护的设计。

     假定Oozinoz公司的工程师在使用图像代理时,出于性能上的考虑,在载入较大的图像时显示了一个小的临时图像。这位工程师使用了一个原型(请参看程序运行结果)。用于实现该应用程序的代码在app.proxy包的ShowProxy类中。下面的代码将假定该应用程序位于com.oozinoz.imaging包中。

     图形用户界面分别在不同阶段显示这三个视图:一个视图用于表明还未开始加载图像,一个视图用于表明正在加载图像,还有一个视图用于显示实际图像。整个过程如下:当应用程序启动的时候,显示“Absent“图像,这是事先用图像处理工具做好的JPEG图像;当用户单击Load按钮的时候,立即显示我们事先准备的另一张图像"Load...";当图像加载完成之后,显示该图像。

     显示JPEG图像最简单的做法就是:创建一个ImageIcon对象,然后将它作为参数实例化一个标签类。代码如下所示:

ImageIcon icon = new ImageIcon("images/fest.jpg"); 
JLabel label = new JLabel(icon); 

 

     在构建应用程序时,我们要创建一个用它实例化JLabel类的代理,并用它转发绘制请求以(1)显示"Absent"图像,(2)显示"loading"图像,或者(3)显示所请求的图像,下图所示的顺序图给出了这个过程的消息流。

 


      
                         ImageIconProxy对象将paint()请求转发给当前的ImageIcon对象 

   当用户单击Load按钮时,ImageIconProxy对象将当前图像改为"loading..."图像,与此同时,该代理对象开始加载指定的图像。当指定图像加载完成后,ImageIconProxy对象将当前图像改为该指定图像。

   如下图所示,我们可以通过创建ImageIcon类的子类来创建代理类。ImageIconProxy类的代码定义了两个静态变量,分别引用了"Absent"图像和"Loading..."图像。

Java代码 复制代码
static final ImageIcon ABSENT = new ImageIcon(
             ClassLoader.getSystemResource("images/absent.jpg"));
static final ImageIcon LOADING = new ImageIcon(
             ClassLoader.getSystemResource("Images/loading.jpg"));



      由于ImageIconProxy对象扩展了ImageIcon对象,因而它可以代理ImageIcon对象

   ImageIconProxy类的构造器以最终要显示的图像文件名为参数。当调用ImageIconProxy对象的load()方法的时候,该方法将当前图像设置成"loading..."图像,并启动一个单独的线程来加载该图像。使用单独的线程可以保证在加载图像的时候应用程序不会被挂起。load()方法以JFrame类对象为参数,当指定图像加载完毕后,就会返回run()方法。ImageIconProxy.java中的代码如下所示:

Java代码 复制代码
package com.oozinoz.imaging;
import java.awt.*;
import javax.swing.*;

public class ImageIconProxy extends ImageIcon implements Runnable
{
     static final ImageIcon ABSENT = new ImageIcon(ClassLoader.getSystemResource("images/absend.jpg"));
     static final ImageIcon LOADING = new ImageIcon(ClassLoader.getSystemResource("images/loading.jpg"));
     ImageIcon current = ABSENT;
     protected String filename;
     protected JFrame callbackFrame;

     public ImageIconProxy(String filename)
     {
          super(ABSENT.getImage());
          this.filename = filename;
     }
    
     public void load(JFrame callbackFrame)
     {
          this.callbackFrame = callbackFrame;
          current = LOADING;
          callbackFrame.repaint();
          new Thread(this).start();
     }
 
     public void run()
     {
          current = new ImageIcon(ClassLaoder.getSystemResource(filename));
          callbackFrame.pack();
     }

     public int getIconHeight()
     {
          return current.getIconHeight();
     }

     public int getIconWidth()
     {
          return current.getIconWidth();
     }

     public synchronized void paintIcon()
     {
          current.paintIcon(c,g,x,y);
     }
}

突破题:ImageIconProxy对象将在三个有关图像显示的调用转发给当前对象。请写出ImageIconProxy类中getIconHeight()方法、getIconHeight()方法以及paintIcon()方法的代码。

 

     假设我们的这个小型演示程序可以运行。实际的应用程序只能会有多个按钮,不过在实际构建这个应用程序之前,我们有必要举行一次设计评审会。只有这样,设计中的脆弱之处才会显露出来。

     

突破题:ImageIconProxy类并不是一个设计良好的、可复用的组件。请指出该设计存在的两个问题。

答:本设计存在问题包括:

    (1)只把部分调用转发给底层的ImageIcon对象是很危险的。ImageIconProxy类从ImageIcon类继承很多字段和大约25个方法。为成为真正的代理,ImageIconProxy对象需要转发大多数或者全部调用。彻底的调用转发需要很多潜在存在问题的方法,并且需要这部分代码在ImageIcon类及其超类变化时也要做相应调整。

    (2)你也许疑惑空白图片和所需图片是否到位。最好把这些图片直接传递进来,不要让类查找它们。

 

    当评审他人的设计时,我们必须同时形成对该设计的理解和自己对该设计的看法。当开发者正在使用某种特定的设计模式时,我们可能会对是否应使用该设计模式有不同看法。在这个例子中,Proxy模式的使用很明显,但是这并不说明该设计就是合理的;实际上还存在更好的设计。当设计中使用Proxy模式时,应该有充分理由,这是因为转发可能会带来一系列其他设计所能够避免的问题。下一节会重新思考Proxy模式到底是否是明智的选择。

  • 大小: 4.2 KB
  • 大小: 6.7 KB
分享到:
评论

相关推荐

    Proxy代理模式经典实例(绝对OOP)

    Proxy代理模式是面向对象设计模式中的重要组成部分,它在软件工程中扮演着关键角色,尤其在Java编程中。代理模式的主要目的是为一个对象提供一个替身或者占位符,以便控制对这个对象的访问。这种设计模式允许我们...

    Proxy 代理模式

    Proxy代理模式是设计模式中的一种,它在Java中扮演着重要的角色,特别是在处理远程调用、安全性、缓存以及日志记录等方面。代理模式的基本思想是为一个对象提供一个替身或者占位符,以便控制对这个对象的访问。在这...

    详解设计模式中的proxy代理模式及在Java程序中的实现

    综上所述,Proxy代理模式是设计模式中的一个重要组成部分,它允许我们在不改变原始对象的情况下,通过代理对象实现对原始对象的控制和扩展。在Java中,通过Java的Proxy类和InvocationHandler接口,我们可以轻松地...

    C#面向对象设计模式纵横谈(13):Proxy 代理模式(结构型模式)

    ### C#面向对象设计模式纵横谈(13):Proxy 代理模式(结构型模式) #### 重要概念:代理模式 代理模式是一种常用的结构型设计模式,它通过为另一个对象提供一个代理,来控制对该对象的访问。这种模式在软件工程中...

    C#面向对象设计模式纵横谈(13):Proxy 代理模式(结构型模式) (Level 300)

    本文将深入探讨C#中的一个关键设计模式——代理模式,它属于结构型模式的一种,适用于管理和控制对象的访问。我们将从概念、分类、实现方式以及实际应用等方面进行详细的讲解。 1. **代理模式概念**: 代理模式是一...

    C#面向对象设计模式纵横谈\13 结构型模式Proxy代理模式.zip

    在这里与各位分享本人从网络上下载的C#面向对象设计模式纵横谈系列视频,共有25节,除了第一节需要各位贡献一点资源分以作为对本人上传资源的回馈,后面的其他资源均不需要资源... 这是第13节:结构型模式Proxy代理模式

    设计模式C++学习之代理模式(Proxy)

    代理模式是一种设计模式,它是结构型模式之一,主要用于在客户端和目标对象之间建立一个代理对象,以便控制对目标对象的访问。在C++中,代理模式可以用来为其他对象提供一种代理以控制对这个对象的访问,或者增加...

    解析proxy代理模式在Ruby设计模式开发中的运用

    Proxy代理模式是一种结构型设计模式,主要解决的问题是:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全...

    设计模式之代理模式proxy.zip

    代理模式是一种常用的设计模式,它在软件开发中扮演着重要的角色。代理模式允许我们为一个对象创建一个代理,这个代理对象在客户端和目标对象之间起到中介的作用,可以增强或控制对目标对象的访问。代理模式的主要...

    C++设计模式编程中proxy代理模式的使用实例

    代理模式典型的结构图为: 实际上,代理模式的想法非常简单。 代理模式的实现: 完整代码示例(code):代理模式的实现很简单,这里为了方便初学者的学习和参考,将给出完整的实现代码(所有代码采用 C++实现,并...

    设计模式之代理模式proxy

    **设计模式之代理模式(Proxy Pattern)** 设计模式是软件工程中的一种最佳实践,它是在特定情境下解决常见问题的模板。代理模式是其中一种行为设计模式,它的核心思想是为一个对象提供一个替身或者代理,以控制对...

    设计模式之代理模式Proxy

    代理模式是设计模式中的一种结构型模式,它在对象交互中起到了中介的作用,允许通过代理对象来控制对原对象的访问。代理模式的核心思想是为一个对象提供一个替身,以便增加新的功能或者控制对原对象的访问。这种模式...

    结构型模式之代理模式(Proxy)

    代理模式是一种设计模式,属于结构型模式之一,其主要目的是为其他对象提供一个代理,以控制对该对象的访问。在实际应用中,代理模式能够帮助我们实现如下的功能: 1. 远程代理:代理对象可以代表一个位于远程系统...

    Android设计模式之代理模式(Proxy Pattern)

    代理模式是设计模式的一种,它的主要目的是在不改变原有对象的基础上,为一个对象提供额外的功能或者控制对这个对象的访问。在Android开发中,代理模式的应用尤为常见,尤其在处理复杂的业务逻辑、网络请求、界面...

    Proxy Pattern 代理模式

    Proxy Pattern 代理模式 采用JAVA实现,可以下载看看。

    jdbc proxy 代理类

    JDBC代理主要涉及两个技术领域:AOP(面向切面编程)和设计模式中的代理模式。 【描述】:“代码对应的blog:http://blog.csdn.net/keyboardsun/archive/2008/01/30/2072865.aspx” 这个博客文章详细介绍了如何...

    Proxy 模式学习代码

    Proxy模式是一种设计模式,它允许我们为一个对象创建一个代理对象,这个代理对象在客户端和目标对象之间起到中介的作用。这种模式在软件工程中广泛应用,主要用于控制对真实对象的访问,提供额外的功能,如日志、...

    spring proxy代理模仿

    这里我们探讨的“spring proxy代理模仿”主要指的是Spring AOP(面向切面编程)中的动态代理实现。Spring AOP通过代理模式为我们提供了在运行时向目标对象添加拦截器或切面的能力,这在进行日志记录、性能监控、事务...

    c++-设计模式之代理模式(Proxy)

    代理模式(Proxy Pattern)是一种结构型设计模式,用于为其他对象提供一种代理以控制对这个对象的访问。代理模式通常用于保护、延迟加载、记录请求等场景,可以在不改变原有对象的情况下为其增加新的功能。 代理...

Global site tag (gtag.js) - Google Analytics