An overview of the

In some cases, customers cannot or do not want to directly access the target object, so they need to access the target object through agents. For example, customers buy tickets through the railway station agency, and customers buy overseas through “agents” or “intermediaries”. This is an example of the prototype of the agency model in real life

Definition and Features

Definition: Provide a proxy for a target object to provide access to the class

Advantages:

  • Agent between the customer and the target object, so that the customer and the target object separation, reduce the coupling degree of the system
  • Proxy objects extend the capabilities of target objects

Disadvantages:

  • Adding a proxy object between the client and the target object slows requests down
  • Additional classes were added to increase the complexity of the system

implementation

(UML class diagram of the proxy pattern)

We give each class a description as shown above

  • Cliect(Client) : The user, using the proxy class entry
  • Subject (Abstract target class): An abstract or interface class, the common interface methods of the target class and the proxy class
  • RealSubject(Real target class) : Implements an abstract target class that defines the real objects represented by the broker and is responsible for concrete business implementation
  • Proxy(Proxy class) : Holds a reference to the real target class and invokes the methods in the real target class in the implemented interface methods

So let’s write a demo

Public interface Shopping {Object[]doShopping(long money);
}
Copy the code
/** * public class implements Shopping {public static final String implements Shopping = public static final String implements Shopping ShoppingImpl.class.getSimpleName(); @Override public Object[]doShopping(long money) {
        Log.e(TAG,"Shopping taobao, shopping malls, buy buy buy!!");
        Log.e(TAG,"Spent"+money+"Yuan");
        Log.e(TAG,"Bought shoes, clothes, snacks.");
        return new Object[]{"Shoes"."Clothes"."Snack"}; }}Copy the code
/** * public class implements Shopping {private Shopping base; public ShoppingProxy(Shopping shopping){ this.base = shopping; } @Override public Object[]doShopping(long money) {Object[] things = base.doshopping (money); // change the return value.if(things ! = null && things.length > 1) { things[0] ="Something switched!!";
        }

        returnthings; }}Copy the code
/** * Client class */ private voidoperate2(){
        Shopping shopping = new ShoppingProxy(new ShoppingImpl());
        Log.e(TAG,Arrays.toString(shopping.doShopping(100)));
    }
Copy the code

The above is a simple proxy class, which is a static proxy

A dynamic proxy

Static proxy mode needs to write a proxy class for every class that needs a proxy. If there are hundreds of classes that need a proxy, isn’t that exhausting? To implement the proxy pattern more elegantly, the JDK provides a dynamic proxy approach

/** * public class implements InvocationHandler {public static final String implements InvocationHandler = ShopHandler.class.getSimpleName(); public Object base; public ShopHandler(Object base){ this.base = base; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if ("doShopping".equals(method.getName())) {Long money = (Long) args[0]; longreadCost = (long) (money * 0.5);
            Log.e(TAG,"Spent"+readCost+"Yuan"); Object[] things = (Object[]) method.invoke(base,readCost); // change the return value.if(things ! = null && things.length > 1) { things[0] ="Something switched!!";
            }

            return things;
        }

        if ("doSomething".equals(method.getName())) {// Can do something elsereturn null;
        }

        if ("doSomethingElse".equals(method.getName())) {// Do something elsereturn null;
        }

        returnnull; }}Copy the code
/** * Client class */ private voidoperate() { Shopping shop = new ShoppingImpl(); Log.e(TAG, arrays.tostring (shop.doshopping (100))); shop = (Shopping) Proxy.newProxyInstance(Shopping.class.getClassLoader(), shop.getClass().getInterfaces(),new ShopHandler(shop)); Log.e(TAG, Arrays.toString(shop.doShopping(100))); }Copy the code

Dynamic proxies are implemented as shown above

Static versus dynamic proxies

  • Static proxy: The proxy class exists before the program runs
  • Dynamic proxy: Proxy classes are dynamically generated based on reflection during program execution

Application scenarios

When an object cannot or does not want to directly access another object, it can be accessed indirectly through a proxy object. To ensure transparency for client use, delegate objects and proxy objects implement the same interface

If the accessed object does not want to expose all of its content, it can be brokered to remove unwanted content

According to the scope of application, proxy modes can be divided into the following types:

  • Remote proxy: Provides a local representation of an object in different address Spaces so that the system can hide the Server part of the business.

  • Virtual proxy: If you want to create a resource-intensive object, you can represent it with a proxy object and create it only when you really need it.

  • Protected proxy: Proxy objects control access to an object and provide different access permissions to different users.

  • Smart References: Append extra operations to references to the original object and add a reference count to references to the original object