Agent pattern and aspect oriented design pattern

The observer mode was mentioned earlier. By the way, the factory mode and aspect oriented mode are mentioned here. Let's use dynamic agent to realize aspect oriented and use configuration file to realize component management. This is also a blog post written before.

What is AOP

In human terms, it is aspect oriented programming. What aspect is aspect that has little to do with the main function of our program. For example, the log function of the program has no impact on the main function of the program, but sometimes it is necessary, but sometimes I don't want it to appear in my main program, This means that this section must be relatively independent of my main program and can be assembled when I need it. In fact, the so-called slice can refer to the one with independent functions. Each face will not affect each other, but it can be used in a combination.

example

In this example, we will use an instance of dynamic agent to write in the mode of AOP.

Dynamic written by agent

Let's first assume an example, and write it with the example of buying a house and looking for an intermediary

Flowchart of Dome

In order to facilitate the understanding of the blog, we first look at two flow charts, one is the flow chart of buying a house (agent), and the other is the complete flow chart.

Agent flow chart

Complete process

Project structure of Dome

The name is very clear. The next thing to explain is that the project is under a package day07.

Complete code

According to the flow chart, the agent part is given first, and then the reflection part is given.

package day07;
public interface BuyHouse {
    public void buyHouse();
}

Copy code
package day07;
public class PersonBuyHouse implements BuyHouse {
    public void buyHouse(){
        System.out.println("I'm very satisfied with the house. I'll pay for it in full!");
    }
}

Copy code
package day07;
public interface HouseAgency {
    public void FindHouse();
}

Copy code
package day07;

public class HouseAgent implements HouseAgency {

    @Override
    public void FindHouse() {
        // TODO Auto-generated method stub
        System.out.println("Looking for listings");
        System.out.println("Listings have been found to meet customer needs");
    }
    
}

Copy code

Configuration file bean properties

bean.PersonBuyHouse = day07.PersonBuyHouse
bean.HouseAgent = day07.HouseAgent
bean.SendAgentFindHouse = day07.SendAgentFindHouse
 Copy code
package day07;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//Factory class, let the intermediary send an intermediary to find a house
public class SendAgentFindHouse implements InvocationHandler {

    private HouseAgency houseAgency;
    private BuyHouse buyHouse;
    public Object SendAgent(){
        Object proxy = null;
        proxy = Proxy.newProxyInstance(buyHouse.getClass().getClassLoader(),buyHouse.getClass().getInterfaces(), this);
        return proxy;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // The intermediary looks for a house and the user pays
        houseAgency.FindHouse();
        buyHouse.buyHouse();
        return null;
    }
    public HouseAgency getHouseAgency() {
        return houseAgency;
    }


    public void setHouseAgency(HouseAgency houseAgency) {
        this.houseAgency = houseAgency;
    }


    public BuyHouse getBuyHouse() {
        return buyHouse;
    }


    public void setBuyHouse(BuyHouse buyHouse) {
        this.buyHouse = buyHouse;
    }

    
}

Copy code
package day07;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;





public class BeanFactory {
    private Properties prop = new Properties();
    public BeanFactory(InputStream in){
        try {
            prop.load(in);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public BeanFactory(InputStreamReader in){
        try {
            prop.load(in);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public Object getBean(String name){
        Object bean=null;
        try {
            Class<?> beanClass = Class.forName(prop.getProperty(name));
            bean = beanClass.getConstructor().newInstance();
            Object buyhouse = Class.forName(prop.getProperty("bean.PersonBuyHouse")).getConstructor().newInstance();
            Object houseagent = Class.forName(prop.getProperty("bean.HouseAgent")).getConstructor().newInstance();
            BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);
            PropertyDescriptor[] propertyDescriptor = beanInfo.getPropertyDescriptors();
            for(PropertyDescriptor pd:propertyDescriptor){
                if(pd.getName().equals("houseAgency")){
                    pd.getWriteMethod().invoke(bean, houseagent);
                }else if(pd.getName().equals("buyHouse")){
                    pd.getWriteMethod().invoke(bean, buyhouse);
                }
            }
            

        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IntrospectionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



        return bean;


    }
    
}

Copy code
package day07;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

public class AOPDomeTest {
    public static void main(String[] args) {

        InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("day07/bean.properties");
        try {
            BeanFactory beanFactory = new BeanFactory(new InputStreamReader(in,"utf8"));
            SendAgentFindHouse sendAgentFindHouse = (SendAgentFindHouse) beanFactory.getBean("bean.SendAgentFindHouse");
            BuyHouse buyHouse = (BuyHouse) sendAgentFindHouse.SendAgent();
            buyHouse.buyHouse();




        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
}

Copy code

summary

According to the above example, it may not be very vivid. However, through coding and flow chart, it can be found that buying a house has no direct relationship with the intermediary in the code, but it can be quickly combined when we need it, and each module is relatively independent and extensible. It can be highly extensible through the configuration file, We only need to modify the configuration file, and we don't even need to rewrite the code. So this mode is the AOP mode. At present, a large number of frameworks are using this mode, which will be seen in the future when studying the Spring framework.

supplement

Java proxy mode

This agent is not the little partner of the other agent (playing crawler, playing penetration, playing over the wall). Please keep calm. This is actually a design pattern. Its function is to implement another class method through another proxy method. In real life, for example, you want to buy something and then go to buy it on behalf of others. This is what the flow chart looks like. (here is an example)

agent

There are two kinds of agents, one is static agent and the other is dynamic agent. This thing is mainly realized through reflection.

Static proxy

Here is a direct example of purchasing clothes from overseas.

public class interface Buy{
	//The thing you want to do, the public interface
	public void buy();
}

public class Person implement Buy{

	public void buy(){
	Sysout.out.println("Very satisfied with the goods, payment");
	//For Person, it's good to pay for clothes, and other things will be done by purchasing agents
	}
}

public class BuyProxy implement Buy{
	//A person who specializes in purchasing on behalf of others, first determines the object of purchasing on behalf of others, and then helps him buy on behalf of others
	private Buy buyer;
	public void BuyProxy(Buy buyer){
		this.buyer = buyer
	}
	public void buy(){
	 	System.out.println("Suitable goods have been found");
	 	buyer.buy();
	}

}

class Test{

	public static void main(String[] args){
		Buy you = new Person();
		BuyProxy buyproxy = new BuyProxy(you);
		buyproxy.buy();
	}
}
Copy code

In the above process, it looks a bit like our python installer. But there are some differences. python does an overlay operation. Of course, you don't need @ this syntax sugar bean, and then you can distinguish our decorated method from the original method (python is not a pure object-oriented computer language after all).

Dynamic agent

We have to mention our reflection mechanism here. The advantage of this dynamic method is to write a new dynamic method without writing an interface like static. This is totally unnecessary. The most important is through proxy Newproxyinstance() is used to help us generate a proxy class. Here are the examples:

public interface Subject {
	//Purpose of shopping
    public void shopping(int mon);
}



import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class CreateProxy implements InvocationHandler {

    private Object target;//The object that needs to be represented, that is, the object of the person who buys clothes

    //Create proxy object
    public Object create(Object target){
        this.target = target;
        Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);

        return proxy;
        
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // TODO Auto-generated method stub
        //Method to be implemented by proxy object

        System.out.println("Looking for products from overseas");
        System.out.println("Found");
        method.invoke(target, args);//args will be passed in if there are parameters
        return null;
    }
    
}


public class Person implements Subject {

    @Override
    public void shopping(int mon) {
        // TODO Auto-generated method stub
        System.out.println("Buy a dress,Satisfactory payment");
        System.out.println("Here it is"+mon+"Money");
        
    }
    
    
}


public class BuyDoingTest {
    
    public static void main(String[] args) {
        CreateProxy cp = new CreateProxy();
        Subject person = new Person();
        Subject proxy = (Subject)cp.create(person);
        proxy.shopping(30);//invoke is called
    }
    
}

Keywords: Java Back-end Programmer

Added by aeonsky on Wed, 09 Feb 2022 21:13:47 +0200