Proxy pattern of Java design pattern

Keywords: Android Java JDK

Proxy pattern is one of the common design patterns in Java. The so-called proxy mode means that the client does not directly call the actual object, but indirectly calls the actual object by calling the proxy.
Why call objects in this indirect form? Generally, because the client does not want to access the actual object directly, or because it is difficult to access the actual object, it can complete indirect access through a proxy object.
In real life, this kind of situation is very common, such as inviting a lawyer to act for a lawsuit.
The code for the following example is accessible Source code . Welcome to star, welcome to fork

UML diagrams of proxy patterns

From the UML diagram, we can see that both the proxy class and the real implemented class inherit the abstract subject class. The advantage of this is that the proxy class can have the same method as the actual class, which can ensure the transparency of the client's use.

Implementation of Agent Model

The proxy pattern can be implemented in two ways, one is static proxy class, the other is dynamic proxy which every framework likes. Next, let's talk about these two agent models.

Static proxy

Let's first look at the example of UML implementation above, and then at the characteristics of static proxies.
Implementation of Subject Interface

public interface Subject {
    void visit();
}

Two classes of Subject interface are implemented:

public class RealSubject implements Subject {

    private String name = "byhieg";
    @Override
    public void visit() {
        System.out.println(name);
    }
}
public class ProxySubject implements Subject{

    private Subject subject;

    public ProxySubject(Subject subject) {
        this.subject = subject;
    }

    @Override
    public void visit() {
        subject.visit();
    }
}

Specific calls are as follows:

public class Client {

    public static void main(String[] args) {
        ProxySubject subject = new ProxySubject(new RealSubject());
        subject.visit();
    }
}

Through the above proxy code, we can see the characteristics of the proxy mode. The proxy class accepts an object of Subject interface. Any object that implements the interface can be proxyed through the proxy class, which increases the generality. However, there are also drawbacks. Each proxy class must implement the interface of the delegate class (that is, realsubject) once. If the interface adds methods, the proxy class must also be modified. Secondly, each interface object of the proxy class corresponds to a delegate object. If there are many delegates, the static proxy class is very bulky and incompetent.

Dynamic proxy

Dynamic proxy is different from static proxy. It creates proxy class dynamically according to the object of proxy. In this way, we can avoid the problem of too many proxy class interfaces in static proxy. Dynamic proxy is implemented by reflection. It is generated by fixed rules with the help of Java's own java.lang.reflect.Proxy.
The steps are as follows:

  1. Write an interface for a delegate class, the Subject interface of a static proxy
  2. Implementing a real delegate class, the RealSubject class
  3. Create a dynamic proxy class, implement the InvocationHandler interface, and override the invoke method
  4. In the test class, the dynamic proxy object is generated.

The first two steps are the same as static proxy, but that's all. Step three, the code is as follows:

public class DynamicProxy implements InvocationHandler {
    private Object object;
    public DynamicProxy(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(object, args);
        return result;
    }
}

Step 4: Create dynamic proxy objects

Subject realSubject = new RealSubject();
DynamicProxy proxy = new DynamicProxy(realSubject);
ClassLoader classLoader = realSubject.getClass().getClassLoader();
Subject subject = (Subject) Proxy.newProxyInstance(classLoader, new  Class[]{Subject.class}, proxy);
subject.visit();

Creating dynamic proxy objects requires the help of Proxy.newProxyInstance. The three parameters of the method are:

  • ClassLoader loader represents the currently used appClassloader.
  • Class <?>[] interfaces represent a set of interfaces implemented by the target object.
  • InvocationHandler h represents the current instance object of the InvocationHandler implementation.

This is where we introduce the use of dynamic proxies. The realization of dynamic proxy, the realization of dynamic proxy with the help of non-JDK libraries, and their advantages and disadvantages will be introduced later.

Posted by gid__ on Sun, 21 Apr 2019 14:33:33 -0700