Design Pattern 5 - Proxy Pattern

1. Definition:

Provides a proxy for other objects to control access to this object.

Second, the general class diagram:


Subject abstract subject role

Generic code:

public interface Subject {
    //define a method
    public void request();
}

RealSubject specific subject role

Generic code:

public class RealSubject implements Subject {
    //Implementation
    public void request() {
        //Business logic processing
    }
}

Proxy agent theme role: responsible for the application of the real role, and do pre-processing and post-processing work.

public class Proxy implements Subject {
    //Which implementation class to proxy
    private Subject subject = null;
    //default proxy
    public Proxy(){
        this.subject = new Proxy();
    }
    //Pass the proxy through the constructor
    public Proxy(Object...objects ){
    }
    //implement the method defined in the interface
    public void request() {
        this.before();
        this.subject.request();
        this.after();
    }
    // preprocessing
    private void before(){
        //do something
    }
    // deal with the aftermath
    private void after(){
        //do something
    }
}

Under normal circumstances, an interface only needs one proxy class, and the specific proxy class is determined by the high-level module. You can add a constructor to the proxy class Proxy:

public Proxy(Subject _subject){
    this.subject = _subject;
}

3. Usage scenarios:

Spring AOP is a very typical dynamic proxy.

Fourth, the expansion of the agent model

1. General agent

Require clients to only have access to proxy roles, not real roles

2. Forced proxy

The concept of forced proxy is to find the proxy role from the real role

3. Focus: dynamic proxy

Dynamic proxy does not need to care about who to proxy in the implementation stage, and only specifies which object to proxy in the running stage. That is, the proxy class is dynamically generated



The Java dynamic proxy class is located under the java.lang.reflect package and involves two classes:

(1) Methods defined in the InvocationHandler transaction processor interface

Object invoke (Object obj,Method method,Object[] args)

obj proxy class, method is the proxy method, and args is an array of method parameters. This abstract method is implemented dynamically in the proxy class

(2) Proxy dynamic proxy class

Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)

Returns an instance of the proxy class. The returned proxy class can be used as a proxy class.


Implementation steps:

(1) Create a class that implements the interface InvocationHandler, which must implement the invoke method

(2) Create proxied classes and interfaces

(3) Call the static method of Proxy to create a proxy class

(4) Call the method through the proxy

The following takes playing a game as an example to implement dynamic proxy:

Game player interface:

public interface IGamePlayer {
    //Log in
    public void login(String user,String password);
    // Daguai
    public void killBoss();
    //upgrade
    public void upgrade();
}

Game player implementation class:

public class GamePlayer implements IGamePlayer {
    private String name = "";
    public GamePlayer(String name){
        this.name = name;
    }
    public void killBoss() {
        System.out.println(this.name + "打怪");
    }
    public void login(String user, String password) {
        System.out.println("login name"+user+"user"+this.name+"login successful");
    }
    public void upgrade() {
        System.out.println(this.name + "Upgrade");
    }
}

Transaction processor:

public class GamePlayIH implements InvocationHandler {
    // Proxy instance
    Object obj = null;
    //Constructor
    public GamePlayIH(Object obj){
        this.obj = obj;
    }
    /**
     */ call the delegated method
     * @param proxy the object to be proxied
     * @param method The method of the proxied object
     * @param args method parameters
     * @return method return value
     * @throws Throwable
     */
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("Start agent");
        Object result = method.invoke(this.obj, args);
        System.out.println("End agent");
        return result;
    }
}

Scene class:

public class Client {
    public static void main(String[] args) throws Throwable {
        IGamePlayer player = new GamePlayer("wbao");
        InvocationHandler handler = new GamePlayIH(player);
        ClassLoader cl = player.getClass().getClassLoader();
        // Dynamically generate a proxy
        IGamePlayer proxy = (IGamePlayer) Proxy.newProxyInstance(cl, player.getClass().getInterfaces(), handler);
        proxy.login("wbao", "password");
        proxy.killBoss();
        proxy.upgrade();
    }
}

Program execution result:

Start proxy
login wbao user wbao login successfully
ends proxy
start proxy
wbao fight monsters
end proxy
start proxy
wbao upgraded
end proxy

Optimization: Simplify scene class calls and increase notification Advice

Class Diagram:





Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325441794&siteId=291194637