Proxy design pattern

Time:2019-10-31

Proxy design pattern

Summary

Before we start the text, let’s consider a question: what’s calledProxy
according toWikipediaDefinition:
Proxy (English: proxy), also known as network proxy, is a special network service, which allows a network terminal (generally the client) to make indirect connection with another network terminal (generally the server) through this service. Some network devices such as gateway and router have the function of network agent. It is generally believed that agent service is beneficial to protect the privacy or security of network terminals and prevent attacks.
Popular talkagentIt is similar to a bridge between the client and the server, connecting the request and response between the client and the server. On the one hand, the existence of the agent can protect the security of the server. On the other hand, it can filter the request information in the agent part, isolate some illegal request information. On the other hand, it can improve the access speed of the user. Its specific functions can be achieved by the help of the following To help understand.
测试
Proxy design pattern

Let’s take another example. Suddenly one day you need to see a famous Wang talking about a project with him. Generally speaking, you can’t go directly to see others, but Wang must have a secretary. You can tell the Secretary in advance, and the Secretary will convey it to Wang on behalf of him. President Wang will let the Secretary inform you if he is interested in this project. In the whole process, you are the client, the secretary is the agent, and Wang is the server.
If you understand the aboveagentSoAgent design patternIt’s not hard to understand.Agent design patternIt’s right up there.Client agent serverAn abstraction of the three links, and then applied to a general design pattern in software development.
The agent design pattern has the following three advantages:

  1. Protect real objects
  2. Make the responsibility of the object clearer
  3. Easy to expand

There are three ways to implement the agent design pattern in java development:

  • Static proxy
  • Dynamic proxy JDK implementation
  • Cglib implementation of dynamic agent
    Next, we discuss and analyze the implementation of these three agent design patterns in three cases.

Static proxy

UML class diagram

Proxy design pattern

  • KeHuClient side
  • MiShhu: Intermediary
  • LaoZongServer
  • GongNeng: functional interface to be implemented by server and mediation at the same time

code implementation

GongNengJava code for:

/**
 * @program: TestBlog
 * @description:
 Functional interface to be implemented by Secretary and manager
 * @author: vcjmhg
 * @create: 2019-10-07 16:31
 **/
public interface GongNeng {
    public void ZuoShengYi();
    public void eat();
}

KehuJava code for

/**
 * @program: TestBlog
 * @description:
 Customer is equivalent to customer service
 * @author: vcjmhg
 * @create: 2019-10-07 16:31
 **/
public class KeHu {
    public static void main(String[] args) {
        MiShu miShu=new MiShu();
        miShu.ZuoShengYi();
    }
}

MiShuJava code for

/**
 * @program: TestBlog
 * @description:
 * @author: vcjmhg
 * @create: 2019-10-07 16:31
 **/
public class MiShu implements GongNeng{
    private LaoZong laoZong=new LaoZong();
    public void ZuoShengYi() {
        System. Out. Println ("Secretary: do you make an appointment? "";
        laoZong.ZuoShengYi();
        System. Out. Println ("Secretary notes visitor information");
    }

    public void eat() {
        System. Out. Println ("Secretary: do you make an appointment? "";
        laoZong.eat();
        System. Out. Println ("Secretary notes visitor information");
    }
}

LaoZongJava code for:

package proxy.staticproxy;

/**
 * @program: TestBlog
 * @description:
 * @author: vcjmhg
 * @create: 2019-10-07 16:31
 **/
public class LaoZong implements GongNeng{

    public void ZuoShengYi() {
        System. Out. Println ("boss: talk about a small project!! "";
    }

    public void eat() {
        System. Out. Println ("boss: eat!! "";
    }
}

The operation result is:

Secretary: do you have an appointment?
Boss: talk about a small project!!
Secretary notes visitor information

Process finished with exit code 0

Code address

For detailed code, please refer to the code on GitHub.

Shortage of static agents

There is no doubt that static agent is the easiest or most intuitive way to implement the agent design pattern. The advantages of agent pattern are inevitable, but on the other hand, it also has many disadvantages:

  1. The proxy class implements the same interface as the delegate class, and the proxy class implements the same method through the delegate class. This leads to a lot of code duplication. If a method is added to the interface, all the proxy classes need to implement this method in addition to all the implementation classes. It increases the complexity of code maintenance.
  2. A proxy object serves only one type of object, if you want to serve multiple types of objects. It is bound to proxy for every object. Static proxy is not competent when the program scale is a little large.
    In order to solve this problem, we introduce dynamic agent

JDK implementation of dynamic agent

UML class diagram

Proxy design pattern

  • ClientClient side
  • MiShhu: Intermediary
  • LaoZongServer
  • GongNeng: functional interface to be implemented by server and mediation at the same time

code implementation

ClientJava code for:

/**
* @program: TestBlog
* @description:
* @author: vcjmhg
* @create: 2019-10-07 17:04
**/
public class Client {
   public static void main(String[] args) {
       //First parameter: classloader used in reflection
       //Second parameter: what interface does proxy need to implement
       //The third parameter: when calling a method through an interface object, which class of invoke method needs to be called
       GongNeng gongneng = (GongNeng) Proxy.newProxyInstance(Client.class.getClassLoader(), new Class[]{GongNeng.class}, new MiShu());
       gongneng.eat();
   }
}

GongNengJava code for:

public interface GongNeng {
   public void ZuoShengYi();
   public  void eat();
}

MiShuJava code for

/**
* @program: TestBlog
* @description:
* @author: vcjmhg
* @create: 2019-10-07 16:56
**/
public class MiShu implements InvocationHandler {
   private LaoZong laozong=new LaoZong() ;
   //Proxy class does not need to repeatedly implement similar functions for the proxied object.
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       System. Out. Println ("appointment time");
       Object result = method.invoke(laozong, args);
       System. Out. Println ("record visitor information")
       return result;
   }
}

LaoZongJava code for:

/**
 * @program: TestBlog
 * @description:
 * @author: vcjmhg
 * @create: 2019-10-07 16:49
 **/
public class LaoZong implements GongNeng{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    public void ZuoShengYi() {
        System. Out. Println ("boss: talk about business")
    }

    public void eat() {
        System. Out. Println ("boss: eat!! "";
    }
}

The operation result is:

Time of appointment
Boss: eat!
Record visitor information

Process finished with exit code 0

Advantages of using JDK to realize dynamic agent

Compared with the static proxy, JDK is used to realize the decoupling between the proxy class and the functional interface. If a method is added to a delegate class, the code of the delegate class can be almost unchanged, reducing the complexity of the code and making it easier to maintain. On the other hand, code reuse can be realized when different types of objects are proxied.

The deficiency of using JDK to realize dynamic agent

However, there are some shortcomings in the implementation of dynamic agent. Because of the internal realization of agent design pattern with reflection, the system overhead is high and the efficiency is low. Moreover, its delegate class still needs to implement the functional interface, and the code coupling is not low enough.

Code address

For detailed code, please refer to the code on GitHub.

Cglib implementation of dynamic agent

UML class diagram

Proxy design pattern

  • ClientClient side
  • MiShhu: Intermediary
  • LaoZongServer

code implementation

ClientJava code for

public class Client {
   public static void main(String[] args) {
       Enhancer enhancer = new Enhancer();
       enhancer.setSuperclass(LaoZong.class);
       enhancer.setCallback(new MiShu());
       
       LaoZong laozong = (LaoZong) enhancer.create();
       laozong.chifan();
       
   }
}

MiShuJava code for:

public class MiShu implements MethodInterceptor{
    public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
        System. Out. Println ("appointment time");
        Object result = arg3.invokeSuper(arg0, arg2);
        System. Out. Println ("remarks");
        return result;
    }

}

LaoZongJava code for:

public class LaoZong {
    
    public void chifan() {
        System. Out. Println ("eating");
    }

    public void mubiao() {
        System. Out. Println ("target");
    }

The operation result is:

Time of appointment
Having dinner
Remarks

Process finished with exit code 0

Advantages of using cglib to realize dynamic agent

On the one hand, cglib realizes dynamic proxy by bytecode, which is efficient and fast in execution; on the other hand, it decouples the coupling between the delegate class and the function interface, which improves the flexibility of the code.

Code address

For detailed code, please refer to the code on GitHub.