The essence of IOC and AOP

IOC

1 Question leads

In the software development process, dependence is unavoidable. Take the bridge mode as an example, as shown in the figure below.
Insert picture description here
The Face module needs to use the Executor mode. From the design point of view, it is hoped that Face will directly use the abstract Executor, namely AbstractExecutor. But in the actual process, when we need to construct an instance of AbstractExecutor first, we have to go to new ExecutorImpl. Assuming that this class is widely used in code, codes like new ExecutorImpl will appear in many places. Once we extend a new class ExecutorImplTwo, then we have to modify the code of these new ExecutorImpl. This seriously violates the principle of opening and closing .
In order to solve this problem, the factory model appeared. Use the factory pattern to wrap the process of new ExecutorImpl. When there is a need to change new ExecutorImpl to new ExecutorImplTwo, only the implementation in the factory class needs to be changed. This solved the problem to a certain extent. But it still has a fly in the ointment :

  • Although the number of lines of code that needs to be modified when the ExecutorImpl changes is reduced to a certain extent, it is still not absolutely not modified. That is to say, there is no strict opening and closing ;
  • When the construction parameters of the Executor implementation class are inconsistent, the factory method may not be effective at this time. At this time, some people say to use an abstract factory, but unfortunately: you throw the problem to the abstract factory, the construction process of the abstract factory and the construction of interface parameters will also face the same problem. So you just gave the problem to the abstract factory, and it did not fundamentally solve the problem.

2 Solve the problem

To solve the above problems, it is necessary to realize the inversion of control (ie IOC), which is an object-oriented design principle. The most common implementation is dependency injection (ie DI). One of the most famous is the dependency injection feature of spring, which is a powerful dependency injection framework based on the reflection feature of the java language. Of course, dependency injection is only one of its powerful features. For the C++ language, there is no reflection, and a similar reflection function can be realized with the help of templates.

AOP

1 Question leads

In development, we often need to add some supplementary functions before or after a function call, such as adding log printing, interception and filtering. At this time, similar functions can be achieved by using template mode or decorator mode .
The template method is as follows: the
Template method
decoration mode is as follows:
Decorative pattern
whether it is a template method or a decoration mode, the implementer is required to write code in accordance with a fixed routine. If the code we call is the third code that has been written, and it will not be implemented in the way we expected, then the template method and decoration mode will not work . Some people will say that we can use the appearance mode to package, but if we only need to add a line of logs, the cost of mobilizing a large amount of code packaging is not realistic; in addition, if we seamlessly add it in the call flow of the code already written by others At this time, the traditional model cannot achieve seamless insertion of functions without modifying the existing code .

2 Solve the problem

In order to solve the previous problem, a programming idea AOP (Aspect Oriented Program) was proposed, namely aspect-oriented programming. Under the powerful dynamic proxy mechanism of java, it provides the technical feasibility of AOP. Of course, C++ can also use templates to achieve crude AOP, but it is still perceptive to the caller. The AOP of the spring library is used as follows:

  • Define the interface
public interface HelloWorld
{
    
    
    void print();
}
  • Implement the interface
public class HelloWorldImpl implements HelloWorld
{
    
    
    public void print()
    {
    
    
        System.out.println("Enter HelloWorldImpl.print()");
    }
}
  • Realize the aspect
public class TestHandler
{
    
    
    public void test()
    {
    
    
        System.out.println("TestHandler Interceptor");
    }
}
  • spring configuration file aoptest.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
        
        <bean id="HelloWorldImpl" class="com.example.aop.HelloWorldImpl" />
        <bean id="TestHandler" class="com.example.aop.TestHandler" />
        
        <aop:config>
            <aop:aspect id="cutin" ref="TestHandler">
                <aop:pointcut id="allMethod" expression="execution(*com.example.aop.HelloWorld.*(..))" />
                <aop:before method="test" pointcut-ref="allMethod" />
                <aop:after method="test" pointcut-ref="allMethod" />
            </aop:aspect>
        </aop:config>
</beans>
  • Use AOP
public static void main(String[] args)
{
    
    
    ApplicationContext ctx = 
            new ClassPathXmlApplicationContext("aoptest.xml");
        
    HelloWorld hw = (HelloWorld)ctx.getBean("HelloWorldImpl");
    hw.print(); 
}
  • The test output is as follows
TestHandler Interceptor
Enter HelloWorldImpl.print()
TestHandler Interceptor

to sum up

Whether it is IOC or AOP, its emergence is not for new ideas and new ideas. Any great technology is to solve the actual business goals as the first priority. Their direct goal is to decouple and make it strictly in compliance with the principle of opening and closing ; the fundamental goal is to facilitate development and collaboration , that is, to isolate dependencies and parallel development .

Guess you like

Origin blog.csdn.net/fs3296/article/details/103738202