Figure 2. UML diagram of packaging object.
You may think that you can pass. NET framework 2.0. This is possible, but this article does not use this method to make the code backward compatible with other versions. NET Framework 1.x Because there are some language functions, in general, the previous examples do not need to use blending. But blending is still valuable, because through it, developers can mix reusable object behaviors, which can come from other unrelated object hierarchies and achieve more functions than partial classes. When using the partial keyword, the code is added in the same class or type, but the physical location is different. The next mixed example shows that the adding behavior is not specific to the Contact class, but a reusable class named FieldUndoer. FieldUndoer implements the IUndoable interface, which allows the modified object to be restored to its original state.
The public interface is unavailable.
The read-only attribute takes Changes () as a Boolean value.
Child Undo ()
Sub AcceptChanges()
terminal interface
The HasChanges property indicates that if there are changes, Undo will restore the object to its original state, and AcceptChanges will receive the current changes of the object, so every time Undo is called again, it will be restored to the state when the changes were last received. If the interface is implemented in partial classes, these three methods must be repeated in every class that wants to contain the behavior. As a pragmatic programmer, I try to adhere to the principle of "coding once, coding only once", so I never want to repeat any code. I copy and paste as little as possible. By using mixing, I can reuse the FieldUndoer object that implements IUndoable. I mixed this new feature in ServiceManager. All client code still doesn't know the new mix, and it doesn't need to be changed unless it needs to use the IUndoable interface. Change the Contact object in the main form, and then click Undo to test this behavior.
The public shared function GetAllContacts () is used as ContactService. Contact ()
Dim service is ContactService. Service = New ContactService。 service
Show the contact () as a contact service. Contact = service. GetAllContacts
//Wrap each contact object
For contacts with I integer = 0. Length-1
//Create a new instance of the wrapper
//Responsible for packaging our objects.
Dim the packaging cover to packaging cover = new packaging cover.
//Add mixin instance of ContactSave.
Dim saver As ContactSave = new contact save.
Wrapper. AddMixin (protection program)
//Add mixin instance of FieldUndoer
dim undoer As field undoer = New field undoer
Wrapper. AddMixin (revocation)
//Create a new object with contacts.
//and ContactSave implementation
dim wrapped Object As Object = wrencher。 Line feed (contact (I))
//Assign a contact person for our new package.
//Go to the previous contact object
contacts(I)= direct cast(wrapped object,_
Contact service. Contact)
//Note that the packaged objects are still of the same type.
//Assign the newly packaged contact object to the target field.
Savior. Target = Contact (1)
undoer。 Target = Contact (1)
then
Reply to contact person
End function
Combinatorial behavior
Getting in is just the tip of the iceberg. The function that really makes AOP famous is to combine mixed behaviors. Take a new contact object as an example, when ISavable is called. Save method, client code also needs to call IUndoable. AcceptChanges method to revert to the last saved change when IUndoable is called. Cancel it next time. It is easy to browse and add objects in this small main form, but writing rules in any system much larger than the user interface will be a heavy task. You need to find all the calls to the Save method, and then add another call to AcceptChanges. And in the process of creating new code, developers also need to remember that this new function will be added every time Save is called. This will soon have a cascade effect, which will easily destroy the stable surname of the system and introduce some bugs that are difficult to track. These methods can be combined by using aspect-oriented programming. Specify a pointcut and notification. When calling the Save method, the Contact object will automatically call the background AcceptChanges.
In order to achieve composition in your application, you need to add another line of code in ServiceManager. We added this line of code after adding FieldUndoer.
//Specify the connection point to save and execute the AcceptChanges method.
Wrapper. AddPointcut (save, accept changes)
The AddPointcut method is overloaded with several different signatures, which provides greater flexibility for specifying the tangent point. The AddPointcut we called received a joint name of string type, which was expressed as a Save method, and then received a method named AcceptChanges as an execution notice. To see if this works, you can set a breakpoint before FieldUndoer. AcceptChanges method and ContactSave. Save methods separately. Clicking the Save button on the main form will intercept the connection, and you will first interrupt the notification AcceptChanges method. The Save method will be executed after the notification is executed.
This simple example shows how to add new behaviors in the whole application, which is very powerful. Despite this feature, it is not just a good new way to add functions. Among many advantages, only a few involve code reuse, and the maintainability of the system can be improved by simplifying the system evolution brought about by new requirements. At the same time, the misuse of AOP will have a significant negative impact on the maintainability of the system, so it is very important to know the timing and methods of using AOP.
How far has AOP gone?
The application of AOP in most large-scale systems or key production systems is not yet fully mature, but with the improvement of language support, the application of AOP will be easier. In addition, improving support is also a new paradigm of software development, such as software factory using aspect-oriented programming. There are several AOP frameworks available in. NET domain, and each framework has its own methods, positive attributes and negative attributes.
Encase-The Encase framework in this code example is just a tool to help you quickly understand and run AOP and understand the concepts behind AOP. Encase applications can be added to aspects of an object separately at runtime.
Aspect #- A CLI-oriented AOP joint compatibility framework that provides a built-in language for declaration and configuration.
The application of rail-rail framework in JIT class of virtual machine.
Spring. . . . -The. NET version of the popular Java Spring framework. AOP will be implemented in the next version.
EOS- aspect-oriented C# extension.