The Proxy Pattern in Java – Java中的代理模式

最后修改: 2019年 7月 18日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

The Proxy pattern allows us to create an intermediary that acts as an interface to another resource, while also hiding the underlying complexity of the component.

代理模式允许我们创建一个中介,作为另一个资源的接口,同时也隐藏了组件的基本复杂性。

2. Proxy Pattern Example

2.代理模式实例

Consider a heavy Java object (like a JDBC connection or a SessionFactory) that requires some initial configuration.

考虑一个沉重的Java对象(如JDBC连接或SessionFactory),需要一些初始配置。

We only want such objects to be initialized on demand, and once they are, we’d want to reuse them for all calls:

我们只想让这些对象在需要时被初始化,一旦它们被初始化,我们就想在所有的调用中重复使用它们。

MrvrsH6

Let’s now create a simple interface and the configuration for this object:

现在让我们为这个对象创建一个简单的接口和配置。

public interface ExpensiveObject {
    void process();
}

And the implementation of this interface with a large initial configuration:

而这个接口的实现,有一个很大的初始配置。

public class ExpensiveObjectImpl implements ExpensiveObject {

    public ExpensiveObjectImpl() {
        heavyInitialConfiguration();
    }
    
    @Override
    public void process() {
        LOG.info("processing complete.");
    }
    
    private void heavyInitialConfiguration() {
        LOG.info("Loading initial configuration...");
    }
    
}

We’ll now utilize the Proxy pattern and initialize our object on demand:

现在我们将利用代理模式,按需初始化我们的对象。

public class ExpensiveObjectProxy implements ExpensiveObject {
    private static ExpensiveObject object;

    @Override
    public void process() {
        if (object == null) {
            object = new ExpensiveObjectImpl();
        }
        object.process();
    }
}

Whenever our client calls the process() method, they’ll just get to see the processing and the initial configuration will always remain hidden:

每当我们的客户端调用process()方法时,他们将只看到处理过程,而初始配置将始终保持隐藏。

public static void main(String[] args) {
    ExpensiveObject object = new ExpensiveObjectProxy();
    object.process();
    object.process();
}

Note that we’re calling the process() method twice. Behind the scenes, the settings part will occur only once – when the object is first initialized.

请注意,我们正在调用process() 方法两次。在幕后,设置部分将只发生一次–当对象第一次被初始化时。

For every other subsequent call, this pattern will skip the initial configuration, and only processing will occur:

对于其他每一个后续调用,这种模式将跳过初始配置,只进行处理。

Loading initial configuration...
processing complete.
processing complete.

3. When to Use Proxy

3.何时使用代理权

Understanding how to use a pattern is important.

了解如何使用一个模式是很重要的。

Understanding when to use it is critical.

了解何时使用它是关键。

Let’s talk about when to use the Proxy pattern:

让我们来谈谈何时使用代理模式。

  • When we want a simplified version of a complex or heavy object. In this case, we may represent it with a skeleton object which loads the original object on demand, also called as lazy initialization. This is known as the Virtual Proxy
  • When the original object is present in different address space, and we want to represent it locally. We can create a proxy which does all the necessary boilerplate stuff like creating and maintaining the connection, encoding, decoding, etc., while the client accesses it as it was present in their local address space. This is called the Remote Proxy
  • When we want to add a layer of security to the original underlying object to provide controlled access based on access rights of the client. This is called Protection Proxy

4. Conclusion

4.总结

In this article, we had a look at the proxy design pattern. This is a good choice in the following cases:

在这篇文章中,我们看了一下代理设计模式。在以下情况下,这是一个不错的选择。

  • When we want to have a simplified version of an object or access the object more securely
  • When we want a local version of a remote object

The full source code for this example is available over on GitHub.

这个例子的完整源代码可以在GitHub上找到