Design pattern - agent pattern

proxy pattern

1. Agent mode

In Proxy Pattern, one class represents the functions of another class. This type of design pattern belongs to structural pattern.

In proxy mode, we create objects with existing objects to provide functional interfaces to the outside world

1.1 INTRODUCTION

Intention: in an object-oriented system, direct access to some objects will bring a lot of trouble to users or system structure for some reasons (for example, some operations need security control). We can add an access to this object when accessing this object

Main solution: I want to do some control when accessing a class.

How to solve: add an intermediate layer.

Key code: combination of implementation and proxy class.

1.2 application examples

When accessing an object, if you need to authenticate, judge or verify the visitor, you can do some processing before accessing, or if you need to print a process log, you can add a log during the access process to facilitate judgment. The agent mode is divided into static agent and dynamic agent

1.3 static agent

Static proxy needs to define an interface or parent class. The proxy object and the proxy object implement the same interface or inherit the same parent class together. This is its disadvantage and inconvenient to expand. When an interface needs to be added, all implementations should add the same interface

1.4 dynamic agent

Dynamic Proxy can directly generate a Proxy object for a target (proxied object) object (which implements some or some interfaces), and use the newInstance reflection in the Proxy to realize the Proxy mode

1.4.1 Java.lang.reflect.Proxy class can directly generate a proxy object

Proxy.newProxyInstance(ClassLoader loader, Class<?>[] Interfaces, invocationhandler h) generates a proxy object

  1. Parameter 1: classloader the classloader of the proxy object generally uses the classloader of the proxy object
  2. Parameter 2: class <? > [] Interfaces the interface to be implemented by the proxy object is generally the interface implemented by the proxy object
  3. Parameter 3:InvocationHandler h (Interface) execution processing class
1.4.2 invoke() method in invocationhandler

Invoke (object proxy, method, method, object [] args) method: call any method of the proxy class, and this method will be executed

  1. Parameter 1: proxy object (use with caution)
  2. Parameter 2: currently executed method
  3. Parameter 3: the parameter passed from the runtime of the currently executed method
  4. Return value: the return value of the current method execution

2. Static proxy code

2.1 defining interfaces
package com.jzj.design.demo.proxyDesign.staticproxy;

/**
 * Method interface
 */
public interface IMethodDAO {
    void doSomeThing();
}
2.2 implementation of original interface

Interface implementation

package com.jzj.design.demo.proxyDesign.staticproxy;

public class LocalMethodImpl implements IMethodDAO {
    @Override
    public void doSomeThing() {
        System.out.println("Original object method call");
    }
}
2.3 implementation of static proxy object

Implement the same interface, initialize the proxy object through the constructor, and call the method through the object call

package com.jzj.design.demo.proxyDesign.staticproxy;

public class StaticProxyMethod implements IMethodDAO {


    private IMethodDAO teachDAO;


    /**
     * Static proxy constructor, initializing interface object
     *
     * @param teachDAO
     */
    public StaticProxyMethod(IMethodDAO teachDAO) {
        this.teachDAO = teachDAO;
    }


    @Override
    public void doSomeThing() {
        System.out.println("The static agent can add log, authentication and other operations at the beginning---------------------");
        teachDAO.doSomeThing();
        System.out.println("The static agent ends, the log is output, and the access ends---------------------");
    }
}

2.4 static proxy results
package com.jzj.design.demo.proxyDesign.staticproxy;

public class StaticProxyMain {
    public static void main(String[] args) {
        IMethodDAO methodDAO = new LocalMethodImpl();
        IMethodDAO staticProxy = new StaticProxyMethod(methodDAO);
        staticProxy.doSomeThing();
    }
}

3. Dynamic proxy code

3.1 defining interfaces
package com.jzj.design.demo.proxyDesign.dynamicproxy;

/**
 * The teacher is at the teaching interface
 */
public interface ITeachDAO {
    void teach();
}

3.2 method realization
package com.jzj.design.demo.proxyDesign.dynamicproxy;

/**
 * Teachers in Teaching
 */
public class TeacherServiceImpl implements ITeachDAO {
    @Override
    public void teach() {
        System.out.println("The original object, the teacher is teaching");
    }
}

3.3 dynamic agent implementation

Construct the object through Proxy newInstance reflection, and then enhance the specific method through InvocationHandler

package com.jzj.design.demo.proxyDesign.dynamicproxy;

import java.lang.reflect.Proxy;

/**
 * Dynamic agent
 */
public class DynamicTeachProxy {
    /**
     * Target object
     */
    private Object target;

    //Constructor initializes the target object
    public DynamicTeachProxy(Object target) {
        this.target = target;
    }


    //Generates a proxy object for the target object reflection
    public Object getProxyInstance() {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                (proxy, method, args) -> {
                    System.out.println("--------Dynamic agent- Teacher's preparation before teaching--------");
                    Object value = method.invoke(target, args);
                    System.out.println("--------Dynamic agent- The teacher finished his work after teaching--------");
                    return value;
                });
    }


}

3.4 dynamic agent results
package com.jzj.design.demo.proxyDesign.dynamicproxy;

public class DynamicTestMain {
    public static void main(String[] args) {
        ITeachDAO target = new TeacherServiceImpl();

        //Create a proxy object for the target object
        DynamicTeachProxy proxy = new DynamicTeachProxy(target) ;
        ITeachDAO proxyObject =(ITeachDAO) proxy.getProxyInstance();
        proxyObject.teach();
    }
}

Tags: Java Design Pattern Dynamic Proxy

Posted on Sun, 05 Sep 2021 18:25:49 -0400 by object