【问题标题】:Usage of Proxy design pattern代理设计模式的使用
【发布时间】:2015-01-20 19:43:38
【问题描述】:

我试图理解代理设计模式。但我无法理解代理设计模式的用法。我从维基百科得到这个代码示例

interface Image {
    public void displayImage();
}

//on System A 
class RealImage implements Image {

    private String filename = null;
    /**
     * Constructor
     * @param filename
     */
    public RealImage(final String filename) { 
        this.filename = filename;
        loadImageFromDisk();
    }

    /**
     * Loads the image from the disk
     */
    private void loadImageFromDisk() {
        System.out.println("Loading   " + filename);
    }

    /**
     * Displays the image
     */
    public void displayImage() { 
        System.out.println("Displaying " + filename); 
    }

}

//on System B 
class ProxyImage implements Image {

    private RealImage image = null;
    private String filename = null;
    /**
     * Constructor
     * @param filename 
     */
    public ProxyImage(final String filename) { 
        this.filename = filename; 
    }

    /**
     * Displays the image
     */
    public void displayImage() {
        if (image == null) {
           image = new RealImage(filename);
        } 
        image.displayImage();
    }

}

class ProxyExample {

   /**
    * Test method
    */
   public static void main(String[] args) {
        final Image IMAGE1 = new ProxyImage("HiRes_10MB_Photo1");
        final Image IMAGE2 = new ProxyImage("HiRes_10MB_Photo2");

        IMAGE1.displayImage(); // loading necessary
        IMAGE1.displayImage(); // loading unnecessary
        IMAGE2.displayImage(); // loading necessary
        IMAGE2.displayImage(); // loading unnecessary
        IMAGE1.displayImage(); // loading unnecessary
    }

}

在这个例子中,他们说第二次显示图像不需要加载。甚至可以直接访问 RealImage 对象。

            final Image IMAGE1 = new RealImage("HiRes_10MB_Photo1");
            final Image IMAGE2 = new RealImage("HiRes_10MB_Photo2");

            IMAGE1.displayImage(); // loading necessary
            IMAGE1.displayImage(); // loading unnecessary
            IMAGE2.displayImage(); // loading necessary
            IMAGE2.displayImage(); // loading unnecessary
            IMAGE1.displayImage(); // loading unnecessary

我需要了解 ProxyImage 类在这个模式中的用法。

【问题讨论】:

  • 你对哪一部分感到困惑?
  • 这里他们使用 ProxyImage 的对象实例来显示图像而无需再次重新加载。如果我们也有 RealImage 的对象实例,我们可以归档同样的东西。为什么这被视为一种模式。
  • 谨防维基百科上的模式示例。如果您想要 Java 中最常用的模式,Cay Horstmann's Object-oriented Design & Patterns 很好。该链接的页面上有源代码。

标签: java design-patterns


【解决方案1】:

你知道,我同意你的看法。我觉得有一个更好的例子,他们可以将其用于代理模式。 This seems to use the same example but it's explained much better. 你应该看看那个。

基本上,这一切都归结为这条评论:

// create the Image Object only when the image is required to be shown

这就是proxy 在此示例中为您提供的好处。如果您不显示图像,则无需支付加载它的罚款:

package proxy;

/**
 * Image Viewer program
 */
public class ImageViewer {


    public static void main(String[] args) {

    // assuming that the user selects a folder that has 3 images    
    //create the 3 images   
    Image highResolutionImage1 = new ImageProxy("sample/veryHighResPhoto1.jpeg");
    Image highResolutionImage2 = new ImageProxy("sample/veryHighResPhoto2.jpeg");
    Image highResolutionImage3 = new ImageProxy("sample/veryHighResPhoto3.jpeg");

    // assume that the user clicks on Image one item in a list
    // this would cause the program to call showImage() for that image only
    // note that in this case only image one was loaded into memory
    highResolutionImage1.showImage();

    // consider using the high resolution image object directly
    Image highResolutionImageNoProxy1 = new HighResolutionImage("sample/veryHighResPhoto1.jpeg");
    Image highResolutionImageNoProxy2 = new HighResolutionImage("sample/veryHighResPhoto2.jpeg");
    Image highResolutionImageBoProxy3 = new HighResolutionImage("sample/veryHighResPhoto3.jpeg");


    // assume that the user selects image two item from images list
    highResolutionImageNoProxy2.showImage();

    // note that in this case all images have been loaded into memory 
    // and not all have been actually displayed
    // this is a waste of memory resources

    }

}

【讨论】:

  • 已经有一段时间了,但我建议将其标记为答案
  • @Daniel Kaplan 但是HighResolutionImage 可以修改为仅在调用highResolutionImageNoProxy2.showImage(); 时才加载图像,在这种情况下它也只加载特定对象的 showImage() 方法调用?
【解决方案2】:

代理的意思是“代替”、代表“或代表他人的权力,或者可以用来代表某物价值的数字。 代理设计模式也称为代理、句柄和包装器。

当我们想要创建一个包装器来覆盖客户端的主要对象的复杂性时使用它。

代理设计模式的一些真实世界示例:

  1. 银行的支票或信用卡可以代表我们银行帐户中的内容。它可以用来代替现金,并在需要时提供一种获取现金的方法。而这正是代理模式所做的——“控制和管理对他们保护的对象的访问”。

  2. 一个公司或公司曾经有一个限制很少网站访问的代理。代理首先检查您要连接的主机,如果它不是受限站点列表的一部分,则它会连接到真实的互联网。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 2013-08-20
    • 2021-12-13
    • 2012-03-08
    • 1970-01-01
    • 2011-06-29
    • 2010-10-08
    • 1970-01-01
    相关资源
    最近更新 更多