Static agent & dynamic agent

agent

Role of agent model

  • Function enhancement: additional functions are added to the original functions
  • Control access: the proxy class does not allow access to the target class. For example, class B is a class a proxy, and class C cannot directly access class A, but only through class B; Another example: the merchant (the manufacturer's agent) does not allow users to access the manufacturer

Static proxy

The proxy class is implemented manually. Create a java class to represent the proxy class

Simulate notebook purchase behavior using a static agent:
User: customer class
Merchant: agent class, acting for a brand of notebook
Manufacturer: target class
Three relationships: users -- Merchants -- manufacturers

Implementation steps
  • Create an interface to define the method of selling notebooks
  • Create merchant classes and factory classes to implement the above interfaces
  • Create customer class and buy notebook
Sales interface
public interface NoteBookSell {
    //Obtain the price of a single piece according to the quantity purchased
    public int getPrice(Integer num);
}
ASUS notebook factory
//ASUS notebook factory
public class ASUSfactory implements NoteBookSell {
    @Override
    public int getPrice(Integer num) {
        return num > 200 ? 2499 : 2699;
    }
}
Taobao agent
//Taobao agent
public class Taobao implements NoteBookSell {
    private static ASUSfactory asuSfactory;
    private static double price;//Taobao selling price

    static{
        asuSfactory = new ASUSfactory();
        //Wholesale unit price of 500 pieces
        int price1 = asuSfactory.getPrice(500);
        //Initialize sale price
        price = price1 + price1 * 0.3;
    }
    @Override
    public int getPrice(Integer num) {
        //If the customer buys more than or equal to 2 pieces at one time, 95% off each piece
        return (int)(num >= 2 ? price * 0.95 : price);
    }
}
Jingdong agent
//Jingdong agent
public class Jingdong implements NoteBookSell {
    private static ASUSfactory asuSfactory;
    private static double price;//JD selling price

    static{
        asuSfactory = new ASUSfactory();
        //Wholesale unit price of 500 pieces
        int price1 = asuSfactory.getPrice(500);
        //Initialize sale price
        price = price1 + price1 * 0.3;
    }
    @Override
    public int getPrice(Integer num) {
        //If the customer buys more than or equal to 5 pieces at one time, 85% off each piece
        return (int)(num >= 2 ? price * 0.85 : price);
    }
}
main class (imitating customer class)
public class Main {
    public static void main(String[] args) {
        Taobao taobao = new Taobao();
        int price = taobao.getPrice(1);
        System.out.println("Unit price of a ASUS notebook purchased on Taobao: "+price);
        int price1 = taobao.getPrice(3);
        System.out.println("Unit price of 3 Asus notebooks purchased on Taobao: "+price1);
        
        System.out.println("################################");

        Jingdong jingdong = new Jingdong();
        int price2 = jingdong.getPrice(1);
        System.out.println("Unit price of a ASUS notebook purchased on jd.com: "+price2);
        int price3 = jingdong.getPrice(6);
        System.out.println("Unit price of 6 Asus notebooks purchased on jd.com: "+price3);
    }
}
Operation results

Buy a ASUS notebook on Taobao unit price: 3248
Purchase 3 Asus notebooks on Taobao unit price: 3086
################################
Purchase an ASUS notebook on jd.com unit price: 3248
Purchase 6 Asus notebooks on jd.com unit price: 2761

Dynamic agent

Implementation of dynamic agent

  • jdk dynamic proxy: use Java reflection mechanism to realize the function of dynamic proxy. Write an implementation class that implements InvocationHandler to enhance the target class.
  • Reflection package: Java Lang. reflect, which has three important classes: InvocationHandler, Method and Proxy.
  • Cglib dynamic proxy: cglib is a tool library provided by a third party to create proxy objects.
  • The principle of cglib is inheritance. By inheriting the target class, create its subclass, and override the methods with the same name of the parent class in the subclass to modify the function. Therefore, it is required that the target class and target method cannot be final modified. When spring(AOP) and Hibernate are applied, the agent efficiency of cglib is higher than that of JDK.

Note: JDK dynamic proxy is the interface of proxy, so cast should be converted to interface instead of implementation class. If the implementation class is forcibly converted, ClassCastException will be thrown. For example, ArrayList and LinkedList implement a unified interface List. They cannot convert each other, but they can be transformed upward.

Sales interface
public interface NoteBookSell {
    //Obtain the price of a single piece according to the quantity purchased
    public int getPrice(Integer num);
}
ASUS notebook factory
//ASUS notebook factory
public class ASUSfactory implements NoteBookSell {
    @Override
    public int getPrice(Integer num) {
        return num > 200 ? 2499 : 2699;
    }
}
Implementation class of InvocationHandler
//Implement InvocationHandler interface in reflection
public class SellNoteBookHandler implements InvocationHandler {

    //Target factory class requiring proxy
    private NoteBookSell target;

    public SellNoteBookHandler(NoteBookSell noteBookSell){
        target = noteBookSell;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //Wholesale unit price of 500 pieces
        int price = (int)method.invoke(target, 500);
        //Initialize sale price
        double price1 = price + price * 0.3;
        return (int)((int)args[0] >= 2 ? price1 * 0.95 : price1);
    }
}
main
public class Main {
    public static void main(String[] args) {
        ASUSfactory asusfactory = new ASUSfactory();
        InvocationHandler handler = new SellNoteBookHandler(asusfactory);
        //Create ASUS notebook agent
        NoteBookSell proxy = (NoteBookSell)Proxy.newProxyInstance(asusfactory.getClass().getClassLoader(), asusfactory.getClass().getInterfaces(), handler);
        //When the method in the class is executed through the proxy, the invoke method in InvocationHandler is executed
        //public Object invoke(Object proxy, Method method, Object[] args)
        //The parameters in invoke are passed through the jdk itself; Proxy: the above agent proxy, method: the object obtained by the following getPrice method name, args[0]: the following parameter 5
        int price = proxy.getPrice(5);
        System.out.println("Unit price of a ASUS notebook purchased through an agent: "+price);
    }
}

Keywords: Java

Added by nmpku on Wed, 19 Jan 2022 22:11:26 +0200