Gary Pollice, Professor of Practice, Worcester Institute of Technology
May 15, 2006
A review of the concept of AOP
If you are unfamiliar with AOP, there are a lot of introductory articles about it, including the articles I published in February 2004. 2 A lot, maybe not all, introduction to AOP use the log as an example to illustrate aspects of the concept. (logs are something that many people understand, and it's a good example of how AOP can be used.) ) concern is crosscutting. That is to say, they cannot be simply grouped into one category. However, if we follow the object-oriented paradigm Strictly, we need to integrate these services into a unified, maintainable way. Typically, the responsibility for crosscutting is delegated to a single helper class and relies on each class to require functionality expressed by the aspect, including the invocation at the right place. It is more difficult to ensure that developers always insert a login at the appropriate point in the code. Aspect provides a mechanism to improve the situation, even though it is not perfect.
There are some concepts you need to know so that you understand this discussion about AOP. The main concept is the connection point. This is a concept that all programmers are familiar with, but we now have a new name for it. A connection point is a point that is defined explicitly in the program flow. 3 A connection point has many types, as a call to a method or the return of a method can be a normal return or throw an exception.
With AOP, we need a way to identify the connection points in a program. ASPECTJ uses pointcuts to describe one or more connection points. A pointcut is an expression used to describe a set of connection points. You can think of the pointcut as a query to your code and use it to return a series of connection points.
When you select a series of connection points, you can provide them with reference advice. A reference recommendation is an executable encoding that needs to be run when a connection point encounters a program running. Connection points, pointcuts, and reference recommendations focus on the dynamic properties of your software. The reference suggestion changes the operating characteristics of the program code.
There is a static feature that can handle your system. is a declaration between types. A declaration between types allows you to change the dynamic structure of a program. You can add programs and variables and change the hierarchy of inheritance according to special rules.
As a class is a modular unit of Java, the aspect is the ASPECTJ Modular add-on unit. Aspect encapsulates a crosscutting focus, a point of entry, a declaration between types, and a reference recommendation. AOP is not an alternative to object-oriented analysis and design. It constructs an object-oriented paradigm by dealing with situations where many object-oriented methods do not adequately provide the most appropriate scenario.
AOP Instances
Now let's look at an example of where AOP can be used. Some instances can be found in production systems, while others can be found in production and development environments. Let's start with a couple of developer examples.
Execution Tracking
I was surprised that so many developers put some types of print statements into their encodings to debug or track the execution of a program. I find that the debugger is good at giving information. But we're not here to talk about the value of your debugger. Of course, there are reasonable reasons to want to produce some text-tracking information for your program. In Eclipse's current set of AspectJ Development Tools (AJDT), there is a good example of an aspect that implements the process of tracking a program. In Eclipse's help, there is a detailed description of this example. You can find it in the ASPECTJ Programming Guide.
Instance has a small Java application that has many classes to represent two-dimensional graphics, like circles and squares. It also has a main program to create two circles and a square, and print out their aspects, such as area, perimeter, and the distance between their center points. When you run the program, you will get the output as shown in Figure 1.
Figure 1: Input from a shape program
If we want to see the true order of the program calls, we have two choices. The first method is that we can insert the encoding at the beginning of each program, so that we can print a message with the name of the program and class, and the fact that the program has been entered. We need to do the above process for each program. The second approach is to create an aspect to do exactly the same thing. In this way, we don't need to change any code for the application.
The trace instance contains several versions of the use aspect tracking workaround. Let's look at the final version. For other versions of the discussion, see the discussion in ASPECTJ Programming Guide.
A solid tracking mechanism solution consists of two files. The first one is an abstract aspect. Some encodings of an abstract class are left to programmers, which programmers use to execute in an exported class, or in an export aspect. This abstract aspect, called Trace, has several standard programs that print information about entering and exiting a program, or constructing methods, and the results of formatting the output. If we don't use the aspect, these programs will be in a helper class that you can use to output trace information. Trace also allows programmers to set the type of trace by setting a property called TraceLevel. There are three levels: no information, no indented information, and information that is indented to express nested calls.
The trace defines three pointcuts, two of which are concrete and one is abstract, as shown in Figure 2. An abstract pointcut is MyClass, which must be provided by the aspect that can extend trace. The purpose of the pointcut is to select a class for the object that contains the connection point that will be suggested. This lets the developer decide which classes will be included in the trace output result.
Figure 2: The pointcut in the tracking aspect
The Myconstructor pointcut, at the beginning of any construction method, is chosen by MyClass to select a connection point for an object in the class. The connection point is the actual body. MyMethod is similar to Myconstructor, but it chooses any program execution in a selected class. The annotation also omits the execution of the ToString program because it is used in the proposal.
The advice provided is fairly simple. Recommendations inserted before each connection point are executed after the connection point. This is shown in Figure 3.
Figure 3:trace Suggestions in the area
To use trace, you need to extend it and provide a concrete execution for the abstract pointcut. Figure 4 shows the entity tracemyclasses aspects of the instance program. Pointcuts Select only objects for twodshape,circle or square instances. The main program sets the TraceLevel, initializes the trace stream, and the main program that runs the instance.
Figure 4: Specific Tracking aspects
Figure 5 shows the output from the running instance section. Note: The output results print information about each object. This is part of each object's ToString program. Now that the MyClasses Pointcut publishes objects to recommendations, it is easy to add information about objects.
Figure 5: Example of a trace result
There are several benefits to using an AOP approach for tracking than manually inserting tracking code where needed. You only need to place a (two-point) location where all of your code needs to be used for tracking purposes. It is easy to insert and delete trace code. You can easily remove aspects from the build configuration. Keep track of the code wherever you need it, even if you add new methods to the target class. This can eliminate human error. At the same time you know that all the tracking code is deleted and you don't ignore anything when you remove from the build configuration. You have a reusable aspect that can be applied and upgraded.
contract design or defensive programming
Bertrand Meyer introduced the concept of contract design. 4 This principle claims that the designer of a class and the user of the class share the assumptions about the implementation of the class. The contract includes invariants, preconditions and post conditions. Contract design allows class designers to focus on implementing the logic of class functionality without worrying about the validity of the arguments. Of course, the prerequisite is that the contract stipulates the prerequisites for the actual argument. The contract design avoids additional coding and improves performance as long as all customers adhere to the contract.
When you set up a library for extensive use, you may not be able to make assumptions about the validity of arguments and use them in your program. You need to check the arguments before proceeding with the logic of each program. This is an example of defensive programming. You assume that anything that can be wrong may be wrong, and you can solve it perfectly.
Let's say you're going to use the simple state program and make it public. You want to make sure that all the coordinates are in the first Euclidean quadrant--that is, the x and Y coordinates are non-negative. This is a valid constraint so that all points can be well represented in a single window coordinate, since most Windows use the point in the upper-left corner as (0, 0), and the x-coordinate increase is to the right, and the y-coordinate increases as you move down. For your internal needs, you use a contract design to use the class, because you have control of the developer in your organization. When you publish it to an outside client, you check the argument and if the argument is invalid, you give an exception. Aspect provides a first-rate way to achieve it, which is exactly what you want to achieve.
We will establish an aspect to examine all the arguments in the public program. The first thing we have to do is construct the entry point. We'll use the MyClass pointcut from the previous instance and add the Pointcut to select the constructor that needs to check the arguments, and the program guarantees that it does not call an invalid value. Figure 6 shows a set of pointcuts that we need. Note: The second pointcut stipulates that the goal of the Pointcut is an instance of Twodshape. This means that the pointcut in such an object will only select the call to the distance program.
Figure 6: Pointcut to check for arguments
Finally, we need the appropriate notice. For simplicity, when an invalid argument is encountered, we print a message and change the actual value to 0, and in the construction method, the call to distance is ignored when an invalid value is passed. The two notification entries are shown in Figure 7.
Figure 7: Argument checking recommendations
When we try to execute the following statement: Circle C3 = new Circle (3.0,2.0,-2.0);
C1.distance ( null>);
In our program, we get the following output:
Negative argument encountered at:execution (tracing. Circle (double, double
)) All arguments changed to 0.0
Null value given to distance in: Call
(Double trac Ing. Circle.distance (Twodshape))
We can do more work on error information by displaying exact row values and original file names, but this example shows the basic technology.
In a large project, you have a number of classes and expose a few interfaces, and you can use a separate directory for the aspect to organize your code, which in turn enables you to check the arguments. I can imagine several ways of organizing, which can be easily identified and maintained. When you build a system for internal use, you will use an internal build configuration, and when you build it for external use, you will use a configuration that includes aspects. The Eclipse AJDT makes it easy to create new build configurations.
aspects and Design patterns
For good programming, design patterns have become a common approach. AOP can give us a way to improve existing patterns and discover new patterns. In fact, the injection of Crosscutting focus code is a type of pattern. Currently, some researchers are evaluating the implementation of design patterns using AOP methods. Hannemann, a British Columbia University, has been studying the subject as part of his PhD study. His homepage, as well as the code download to implement "gang" mode is located on: http://www.cs.ubc.ca/~jan/AODPs/. 5 Similarly, Nicholas Lesiecki wrote an article about aspects and design patterns for IBM Developerworks. 6 access to his articles can be discussed in more detail than I have provided here.
Let's look at a very simple example of how to implement a standard design pattern, which is a adapter pattern written in AspectJ language.
Figure 8 shows a unified modeling Language (UML) Diagram of the adapter pattern. In this mode, the customer needs a service and wants to set a request for it. There may be many service providers, and each of them may have a different name for the service, or some other non-standard requirements that the service requester must follow. Good object-oriented Design recommends that we integrate service requests into a target interface, program on this interface, and build an adapter. This is required to work as a medium between the customer and the service (Adaptee in the chart).
Figure 8: Adapter Mode
The adapter approach seems to be quite reasonable. But if you have a traditional system, it's not designed with a pattern like an adapter. The original designers were unaware of the possibility of future changes. At the same time, calls to services may run through the entire application. How you will achieve a new, improved service. In no way, you will probably regenerate the system, position each call on the service, design an adapter, and execute the adapter mode. This may be a daunting task, depending on the number of locations where the old service was invoked. Re-improving coding is a worthwhile goal; However, we will not always be so extravagant. We must do our best to be satisfied with the improvement of coding under the limitation of time.
In this case, we can build a version of the adapter pattern to solve the immediate problem and provide a step for a more organized, better designed system.
A simple customer using a service is shown in Figure 9. The service returns the distance from one point to the current client object.
Figure 9: Simple Customer
A simple approach to the interface of a service is described:
The new improved service provider has a method named with a different parameter, and its interface is:
We're going to build an adapter that will be in between calls to the old service, get the right arguments for the new service, invoke the new service, and then return the result to the customer-without changing the customer. As shown in Figure 10:
Figure 10: The adapter aspect of invoking the new service
Notice how simple the aspect is. We describe a pointcut to identify each invocation of the Useservice method of the original service. Then, after extracting the required information from the calling customer, we use a around notification to replace the call with a new service.
This approach has many advantages and benefits. First, we can use a simple aspect to change all the encodings that run through the application. We also integrate the business into a single location to invoke the service. Now, if a new service is replaced by an updated service, we just need to change the code for that aspect. These are certainly good for a more solid system.
The main advantage is that the old customer is still in the system, even if it is not being used. If we have time (which we never seem to have), we will most likely return and regenerate the system to use a more standard adapter pattern. At the very least, we can use the encoding to modify the original service's Useservice program to return a dummy value such as 0.0 because it is never invoked.
Industrial Applications
So far, we've learned a very limited but useful example of applying AOP. We may have to ask what the technical improvement ratio would be. There is an obvious example that I will point out here and briefly describe. For more details, see another article in this column.
Some of you are probably familiar with the Spring framework. The 7 Spring framework is an application framework that supports the development of enterprise applications. It provides a layered Java EE framework to build complex enterprise applications. One of the basic technologies for spring is AOP. Spring has developed its own aspect-oriented implementation, which allows cross logic to be applied to code at run time, rather than through a compiler like ASPECTJ. However, it introduces the integration features that make it easy for you to combine the ASPECTJ with the spring framework.
Spring is currently being used by many organizations to build better enterprise applications that are well designed and require little development time. As far as I can estimate, it is an excellent example of how we apply the aspect to the real problem. 8
Where we are going from here.
In my opinion, AOP will become part of the software Developer's Toolkit in the future. I don't know if we're going to reach the point where AOP is the primary design mechanism when building systems, but I think we'll find ways to enhance our object-oriented design by using aspects. Many things need to be done to help speed up the process.
First, we need some standard AOP implementations that are stable. The process has already begun. ASPECTJ version 5 is the two most popular Java AOP languages, AspectJ and Aspectwerkz merges. Standard implementations in other languages, such as C + +, can also be helpful.
Second, we need to establish metrics that enable us to infer the effectiveness of applying AOP to a particular system. For example, when we re implementing design patterns using AOP, are they better than standard object-oriented patterns? Where they are better and where they are not. What measures do we have to take to get information and develop these metrics? The day of the naïve approach-we believe that if a system is object-oriented (or select your technology), then it's good--it's over. We need to make design and implementation decisions on the basis of empirical data. 9
Third, we need to continue to develop tools that support AOP. I'm happy to say that Eclipse's new ajdt is a great tool. These tools continue to improve our support capabilities, and we need to use them efficiently and efficiently. Tools must also support a new process for processing.
Side still stay here. They are still not a way to become part of the mainstream application, but they are getting closer every day. I recommend that you pay more attention to them and go beyond this curve.
Notes
1 Information about aspectc++ is visible in http://www.aspectc.org/and information about ASPECTL can be referenced http://common-lisp.net/project/closer/aspectl.html
2Rational Edge's February 2004 edition: Http://www.ibm.com/developerworks/rational/library/2782.html
3 The definition I'm using is derived from the excellent ASPECTJ programming guide:http://www.eclipse.org/aspectj/doc/released/progguide/index.html
4 See Bertrand Meyer's, object-oriented Software Construction, 2nd edition. Prentice Hall 1998.
54 people, including Erich Gamma,richard Helm,ralph Johnson and John Vlissides, wrote the design patterns book. This is a book that has a major impact in the design patterns of related books.
6 See http://www-128.ibm.com/developerworks/java/library/j-aopwork5/
7 See http://www.springframework.org/
8 to get more information about the Spring framework, I recommend this book, Pro Spring,rob Harrop and machacek,apress 2005.
9 If a reader is using AOP and would like to discuss their experiences with me and may provide some information for the project I am studying, please contact me.