Explain the design pattern in simple terms - understand the agency pattern from the game

First, the concept of agency mode    

    The so-called proxy mode, as you can see from the name, indirectly accesses the target object through the proxy class.

    A more vivid reflection in football games is: the head coach calls the captain (or other players, let’s designate the captain here) to the sidelines and tells him: XXX is called to participate in the defense or XXX is called to attack. At this time: the captain is the proxy class, and XXX is the target object the head coach wants to visit. The following is an understanding of the proxy mode based on the above scenarios.

2. Usage scenarios

    We can use the proxy pattern to create a proxy class that acts as an intermediary between the client and the target object when one object is inappropriate or cannot directly reference another object.

3. Structure

    The proxy pattern consists of three parts:

        1. Interface (Action): The proxy class and the target object jointly implement the same interface.

        2. Proxy class (Captain): It is used by him to proxy to pass instructions to two target objects.

        3. Target object (Player): The object that specifically executes the command.

4. Realization

    Started the dry goods.

1. Define the interface

public interface Action {

    void attack();  //进攻方法

    void control(); //控制球权方法

    void defend(); //防守方法

}

    Three player actions are defined in the interface: Offense, Control and Defense.

2. Define the actual access object

public class PlayerA implements Action {

    @Override
    public void attack() {
        System.out.println("playerA 开始进攻");
    }

    @Override
    public void control() {
        System.out.println("playerA 控制球权");
    }

    @Override
    public void defend() {
        System.out.println("playerA 参与防守");
    }

}
public class PlayerB implements Action {

    @Override
    public void attack() {
        System.out.println("playerB 开始进攻");
    }

    @Override
    public void control() {
        System.out.println("playerB 控制球权");
    }

    @Override
    public void defend() {
        System.out.println("playerB 参与防守");
    }

}

    Here we define two access objects, player A and player B, both of which implement the Action interface and override the interface methods.

3. Define the proxy class

public class Captain implements Action {

    private Action action;

    Captain(Action action) {
        this.action = action;
    }


    @Override
    public void attack() {
        System.out.println("教练下命令了,叫你进攻。");
        action.attack();
    }

    @Override
    public void control() {
        System.out.println("教练下命令了,叫你控制球权。");
        action.control();
    }

    @Override
    public void defend() {
        System.out.println("教练下命令了,叫你参与防守。");
        action.defend();
    }
}

    The captain is our agent. He also implements the Action interface and provides a constructor that passes in the Action and assigns it to the member variable. The Action method he wants to implement is actually implemented through the member variable action.

4. External Access Objects

public class Coach {

    public static void main(String args[]) {

        PlayerB playerB = new PlayerB();
        PlayerA playerA = new PlayerA();
        
        //队长,你让B开始进攻
        Captain captain = new Captain(playerB);
        captain.attack();
        
        //队长,你让A参与防守
        captain = new Captain(playerA);
        captain.defend();
    }

}

    Well, now the coach is about to start giving orders. First look at the execution result:

   

    It can be seen that the methods we visited are all from captian, but the actual implementation of these methods is indeed player A and player B, catpian plays the role of the microphone very well, and we can also see that the caption is based on the original method. some additions.

    This is the simplest static proxy. At this time, some people will have doubts. What if the message is not the captain but the assistant coach? The assistant coach does not have the three methods of Action, so what should he do if he does not implement the Action interface. Then we need to use dynamic proxy.

Five, dynamic proxy

    The characteristic of dynamic proxy is that the proxy class does not need to implement the interface, and uses reflection to dynamically construct the access object in memory. Proxy in JDK provides us with an API to generate proxy objects. Player A, Player B and Action do not make any changes, let's start making a new proxy class directly

public class Assistant<T> {

    //维护目标对象的Class
    private Class<? extends T> tClass;
    public Assistant(Class<? extends T> tClass) {
        this.tClass=tClass;
    }

    //给目标对象生成代理对象
    @SuppressWarnings("unchecked")
    public T getProxyInstance(){
        return  (T)Proxy.newProxyInstance(
                tClass.getClassLoader(),
                tClass.getInterfaces(),
                (proxy, method, args) -> {
                    System.out.println("开始传达指令");
                    //执行目标对象方法
                    return method.invoke(tClass.newInstance(), args);
                }
        );
    }
    
}

    Now the agent has become an assistant, and he can't act on the field without implementing the Action method. Pass in the Class of the target object in the constructor, and then dynamically generate the target object through the newProxyInstance method of Proxy.

    Well, now the coach is going to give the order.

public class Coach {

    public static void main(String args[]) {
        //助理,准备给A球员下达指令。
        Assistant<Action> actionAssistant = new Assistant<>(PlayerA.class);
        Action action = actionAssistant.getProxyInstance();

        //让A球员进攻
        action.attack();
    }
}

    It can be seen that we give the Assistant a Class of the target object and then get the interface implemented by the target object through getProxyInstance, and get the desired operation through the interface. Let's take a look at the results.

    The proxy is successful. One thing to note for dynamic proxy is that the target object must implement an interface, otherwise the dynamic proxy will be invalid.

6. Advantages

    We mentioned earlier that when an object is inappropriate or cannot directly reference another object, we can establish an intermediary class through the proxy pattern to connect the two objects and protect the target object. We can also process the original method through the proxy mode, which has good scalability.

7. Limitations

    May cause slower access due to the addition of proxy objects between the client and the real object. The proxy mode is more complicated to implement than directly accessing the target object and increases the workload.

    Of course, the same sentence: there is no perfect pattern in the world, every design pattern has its place, as long as we use it properly, then the decorator pattern can help us write beautiful and elegant code.

The source code link is attached for reference: https://gitee.com/jack90john/proxy.git

------------------------------------------------------------------------------

Welcome to pay attention to my personal public account and push the latest articles

Guess you like

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