当前位置:网站首页>Agency mode -- Jiangnan leather shoes factory

Agency mode -- Jiangnan leather shoes factory

2022-06-24 20:34:00 zhanyd

Introduction

Xiaoshuai opened a shoe factory a few years ago , Specializing in the production of men's shoes , Wholesale business , Business was good at first , Life is very moist .

lo , Not for long , We've seen a sharp drop in orders over the past two years , The workers on the production line can't make any money , So they quit one after another , There are only a few old workers left , Once in a while, there is a slightly larger list that can't be accepted .

If we go on like this, we will have to close the door , Shuai has to find another way out . A few days ago, good friends in the industry got together , Good friend Liu Wangxing's factory business is booming , Let Xiaoshuai envy , Shuai thought , Why don't you give your order directly to Liu Wangxing ? Shut down your factory , I'm in charge of receiving orders , Be an agent !

Xiao Shuai and Liu Wangxing hit it off , Cooperation has officially begun .

Xiaoshuai's task is nothing more than to take orders , deliver goods , In order not to let customers know that they are just an agent , Xiaoshuai specially asked the factory to deliver the goods to him first , Put on your own brand , And then send the goods to the customers , Let customers think that shoes are made in their own factory .

The proxy pattern

The whole process is shown in code as follows :

/** *  Shoe factory interface  */
public interface IShoesFactory {
    

    /** *  Visit the factory  */
    void visitFactory();

    /** *  Place the order  * @param price  amount of money  */
    void placeOrder(double price);

    /** *  deliver goods  */
    void ship();
}

/** *  Shoe factory  */
public class ShoesFactory implements IShoesFactory{
    

    private String name;

    public ShoesFactory(String name) {
    
        this.name = name;
    }

    /** *  Visit the factory  */
    @Override
    public void visitFactory() {
    
        System.out.println(" Show clients around " + name);
    }

    /** *  Place the order  * * @param price  amount of money  */
    @Override
    public void placeOrder(double price) {
    
        System.out.println(" Receive " + price + " Order for yuan ");
    }

    /** *  deliver goods  */
    @Override
    public void ship() {
    
        System.out.println(" Start shipping ");
    }
}
/** *  Acting shoe factory  */
public class ShoesFactoryProxy implements IShoesFactory{
    

    private IShoesFactory shoesFactory;

    public ShoesFactoryProxy(IShoesFactory shoesFactory) {
    
        this.shoesFactory = shoesFactory;
    }

    /** *  Visit the factory  */
    @Override
    public void visitFactory() {
    
        shoesFactory.visitFactory();
    }

    /** *  Place the order  * * @param price  amount of money  */
    @Override
    public void placeOrder(double price) {
    
        shoesFactory.placeOrder(price);
    }

    /** *  deliver goods  */
    @Override
    public void ship() {
    
        shoesFactory.ship();
    }
}

Customer class :

public class Client {
    
    public static void main(String[] args) {
    
        IShoesFactory factory = new ShoesFactory(" Liu Wangxing's factory ");
        IShoesFactory factoryProxy = new ShoesFactoryProxy(factory);
        //  Visit the factory 
        factoryProxy.visitFactory();
        //  Place the order 
        factoryProxy.placeOrder(10000);
        //  deliver goods 
        factoryProxy.ship();
    }
}

Output results :

 Take customers to visit Liu Wangxing's factory 
 Receive 10000.0 Order for yuan 
 Start shipping 

The customer is going to visit the factory , Xiaoshuai took the customer to visit Liu Wangxing's factory , Tell the customers that this is their own factory . Customers place orders with Xiaoshuai , Xiaoshuai orders Liu Wangxing for production .

The client class calls the proxy's method , The proxy class then calls the methods of the business class to complete the work .

Proxy pattern definition

The proxy pattern (Proxy Pattern) : Provides a proxy for an object , The proxy object controls the reference to the original object . The English name of agency model Proxy, It's a structural model .

 Insert picture description here
( picture source :https://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/proxy.html)

There is usually at least one real object behind the agent , The external function of the agent is generally the same as that of the actual object , Users deal with agents , No direct contact with real objects , Not even aware of the existence of the actual object .

What's the use of agent mode ? Is it just a forwarding through the proxy class ?

Of course not , Although external functions are the same as real objects , But agency has its value , There are also many types of agents, such as :

  • long-range (Remote) agent : This applies to calling remote server objects , Agents deliver client requests over the network , Responsible for handling all the complicated details related to the network , Simplify the client call .
  • fictitious (Virtual) agent : If you need to create a resource consuming object , Start by creating a relatively small object to represent it , Real objects are actually created only when needed .
  • Copy-on-Write agent : It is a kind of virtual proxy , Copy ( clone ) The operation is delayed until it is actually needed by the client . Generally speaking , Deep cloning of objects is a Expensive operations ,Copy-on-Write The agent can delay this operation , Objects are cloned only when they are used .
  • Protect (Protect or Access) agent : Controls access to an object , Different levels of permissions can be given to different users .
  • buffer (Cache) agent : Provides temporary storage for the results of a target operation , So that multiple clients can share the results .
  • A firewall (Firewall) agent : Protect the target from malicious users .
  • Synchronization (Synchronization) agent : Enables several users to use an object at the same time without conflict .
  • Smart reference (Smart Reference) agent : When an object is referenced , Provide some additional operations , Record the number of times this object has been called, etc .

Let's look at a few examples :

Protection agency

Protect (Protect or Access) The role of agency is , Controls access to an object , Different levels of permissions can be given to different users .

If we don't want customers to access a function , You can do something in the proxy class , After all, business classes are called through proxy classes .

such as , Shuai is afraid to show his true feelings , Don't want customers to visit the factory , You can rewrite the way you visit the factory :
 Insert picture description here
Output :

 It is forbidden to visit the factory 
 Receive 10000.0 Order for yuan 
 Start shipping 

Intelligent reference agent

Smart reference (Smart Reference) The role of agency is , When an object is referenced , Provide some additional operations , Record the number of times this object has been called, etc .

such as , Xiaoshuai as an agent , It must be to make money , The customer's next 10000 Order for yuan , Xiao Shuai talks with Liu Wangxing about the Commission 10%, You can deduct the amount in the agent class .

also , Xiaoshuai's factory has its own brand , You have to put your own brand on it before delivery .

 Insert picture description here
Output :

 It is forbidden to visit the factory 
 Receive 9000.0 Order for yuan 
 Put on the label of Xiaoshuai .
 Start shipping 

Several applications of proxy pattern

  • Picture agent : A very common application example of proxy mode is the control of big picture browsing . When users visit a web page through a browser, they don't load the real big picture first , It's handled through the method of proxy objects , In the method of the proxy object , First use a thread to load a small image to the client browser , Then use another thread in the background to call the big picture loading method to load the big picture to the client .
    When you need to browse big pictures , Then show the big picture in the new page . If the user has not finished loading when browsing the large image , You can start another thread to display the corresponding prompt message . Through agent technology combined with multithreading programming, the loading of real pictures is put into the background to operate , Does not affect the foreground image browsing .
  • Remote agent : Remote agents can hide the details of the network , So that the client does not have to consider the existence of the network . The client can think that the remote business object is local instead of remote , The remote proxy object undertakes most of the network communication work .
  • Virtual agent : When loading an object is very resource intensive , The advantage of virtual agent is obvious . Virtual agent mode is a memory saving technology , Objects that take up a lot of memory or process complexity will be delayed until they are used .

A dynamic proxy

The methods mentioned above are Static proxy pattern , The real business class must be created in advance , And pass it to the proxy object , As an internal member .

Static proxies look like this :
 Insert picture description here
 Insert picture description here

If a real business class must correspond to a proxy class , This will result in a sharp increase in the number of proxy classes in the system , Such as the 10 There are two different business classes , Then there must be 10 A corresponding proxy class , So we need to find a way to reduce the number of classes in the system .

Dynamic proxy can use proxy class without knowing the real business class in advance , During the running of the program JVM According to the mechanism of reflection and other dynamic generation , The typical application of dynamic proxy is Spring AOP.

Let's take a look Java SDK Examples of dynamic agents :

/** *  Shoe factory interface  */
public interface IShoesFactory {
    

    /** *  Visit the factory  */
    void visitFactory();

    /** *  Place the order  * @param price  amount of money  */
    void placeOrder(double price);

    /** *  deliver goods  */
    void ship();
}

/** *  Shoe factory  */
public class ShoesFactory implements IShoesFactory {
    

    private String name;

    public ShoesFactory(String name) {
    
        this.name = name;
    }

    /** *  Visit the factory  */
    @Override
    public void visitFactory() {
    
        System.out.println(" Show clients around " + name);
    }

    /** *  Place the order  * * @param price  amount of money  */
    @Override
    public void placeOrder(double price) {
    
        System.out.println(" Receive " + price + " Order for yuan ");
    }

    /** *  deliver goods  */
    @Override
    public void ship() {
    
        System.out.println(" Start shipping ");
    }
}

InvocationHandler Interface is proxy An interface implemented by the call handler of the proxy instance , Every time the proxy class calls a method, it will enter here invoke Method .

public class ShoesFactoryHandler implements InvocationHandler {
    

    /** *  The proxied object , The actual method practitioner  */
    private Object proxiedObject;

    public ShoesFactoryHandler(Object proxiedObject) {
    
        this.proxiedObject = proxiedObject;
    }

    /** *  Every time the proxy class calls a method, it goes into this  * @param proxy  Represents the proxy object itself , We need to pay attention to , It's not a proxy object  * @param method  Represents the method being called  * @param args  Parameters representing methods  * @return * @throws Throwable */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
        /*if(method.getName().equals("visitFactory")) { System.out.println(" It is forbidden to visit the factory "); }*/
        if(method.getName().equals("placeOrder")) {
    
            //  If it's the order method , To the foundry 9 Discount price 
            method.invoke(proxiedObject, Double.parseDouble(String.valueOf(args[0])) * 0.9);
        }
        else if(method.getName().equals("ship")) {
    
            //  If it's the delivery method , Label before shipping 
            System.out.println(" Put on the label of Xiaoshuai ");
            method.invoke(proxiedObject, args);
        } else {
    
            //  Other methods , Call directly 
            method.invoke(proxiedObject, args);
        }
        return null;
    }
}

Proxy Class call newProxyInstance Method to create a proxy object , above InvocationHandler Object as one of the parameters .

public class ShoesFactoryProxy {
    
    /** *  Generate dynamic agents  * @param proxiedObject  The proxied object , The actual method practitioner  * @return */
    public Object createProxy(Object proxiedObject) {
    
        //  Get the corresponding ClassLoader
        ClassLoader classLoader = proxiedObject.getClass().getClassLoader();
        //  Get all the interfaces 
        Class[] interfaces = proxiedObject.getClass().getInterfaces();
        //  Create a call request handler passed to the proxy class 
        ShoesFactoryHandler handler = new ShoesFactoryHandler(proxiedObject);
        return Proxy.newProxyInstance(classLoader, interfaces, handler);
    }
}

Client class :

public class Client {
    
    public static void main(String[] args) {
    
        IShoesFactory factory = new ShoesFactory(" Liu Wangxing's factory ");
        ShoesFactoryProxy shoesFactoryProxy = new ShoesFactoryProxy();
        IShoesFactory factoryProxy = (IShoesFactory)shoesFactoryProxy.createProxy(factory);
        //  Visit the factory 
        factoryProxy.visitFactory();
        //  Place the order 
        factoryProxy.placeOrder(10000);
        //  deliver goods 
        factoryProxy.ship();
    }
}

Output results :

 Take customers to visit Liu Wangxing's factory 
 Receive 9000.0 Order for yuan 
 Put on the label of Xiaoshuai 
 Start shipping 

This is generally the case for more general dynamic proxy classes :

public class NormalHandler implements InvocationHandler {
    

    /** *  The proxied object , The actual method practitioner  */
    private Object proxiedObject;

    public NormalHandler(Object proxiedObject) {
    
        this.proxiedObject = proxiedObject;
    }

    /** *  Every time the proxy class calls a method, it goes into this  * @param proxy  Represents the proxy object itself , We need to pay attention to , It's not a proxy object  * @param method  Represents the method being called  * @param args  Parameters representing methods  * @return * @throws Throwable */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
           //  Before calling the actual method 
    	   preRequest();
    	   //  Call the actual method 
           Object result = method.invoke(proxiedObject, args);
           //  After calling the actual method 
           afterRequest();
        }
        return result;
    }
}

such , We can be in preRequest() and afterRequest() There are a lot of things to do in the method , Like logging , Record the call time and so on .

summary

Agent mode looks a lot like decorator mode , But their intentions are different , The decorator pattern is to add new behaviors to objects , And the proxy model is a surrogate for real objects , Control access to objects .

such as , Protection agency , Authority control , Keep customers away from certain functions ;
such as , Virtual agent , Before real objects are created , First, return the preset information .

Let's take a look at the advantages and disadvantages of the proxy model :

advantage

  • The proxy pattern coordinates the caller and the called , To some extent, the coupling degree of the system is reduced .
  • You can control the service object without the client being aware of it .
  • Even if the service object is not ready or does not exist , Agents can also work .
  • Comply with opening and closing principle , You can create a new agent without making changes to the service or client .

shortcoming

  • Because the proxy object is added between the client and the real business class , As a result, some types of proxy patterns may slow down the processing of requests .
  • Implementing the proxy pattern requires additional work , Increase the complexity of the program .
原网站

版权声明
本文为[zhanyd]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202211327028892.html

随机推荐