HarmonyOS Development: Realize AOP Code Interpolation Ability

Foreword
this article code case based on api13.
AOP, that is. Aspect Oriented Programming, which it is a programming paradigm designed to improve the modularity of code by separating cross-cutting concerns, separating common concerns such as logging, transaction management, and security controls from core business logic, making code easier to maintain and extend.
When it comes to AOP, the most common thing is log recording. AOP can add logging function to applications by inserting piles of codes without modifying the original business code. Of course, in addition to the logging function, I believe you have certainly seen many statistics of three parties, such as AU, Shence, etc. How do they count the number of page visits? Yes, I used AOP.
AOP, to put it simply and bluntly, is that it can implement the original object method before and after execution. Pile insertion similarly, in the development of Hongmeng, we can also directly replace its methods, how to implement it, and use it after Api 11 Aspect object.
Insert function before method
the addBefore method can insert a function before the execution of the original method of the specified class object. The execution sequence will execute the inserted function first and then the original function.
Parameter Description
parameter Name | type | required | description |
targetClass | Object | yes | the specified class object. |
methodName | string | yes | the specified method name. The read-only method is not supported. |
isStatic | boolean | yes | specifies whether the original method is a static method. true indicates a static method and false indicates an instance method. |
before | Function | yes | the function object to insert. If the function has parameters, the first parameter is this object (if isStatic is true, the class object is targetClass; If isStatic is false, it is the instance object of the calling method), and the remaining parameters are the parameters of the original method. Functions can also have no parameters and do not process when there are no parameters. |
Simple example
A very simple case, there is an object Test, there is a method, return a string.
import util from '@ohos.util'
class Test {
name: string = "AbnerMing"
getName(): string {
return this.name
}
}
@Entry
@Component
struct Index {
build() {
Column() {
Button (click)
.onClick(() => {
let test = new Test()
Console. log ("===raw method fetch:"+test. getName())
util.Aspect.addBefore(Test, "getName", false, (test: Test) => {
Test.name="Programmer's Cry"
})
Console. log ("===append logic to get:"+test. getName())
})
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
The above code, after executing the util.Aspect.addBefore method, will modify the name and call test.getName() again, which will change. You can see the output log:
Of course, you can execute any logic you need here, such as embedding points, printing logs, network requests, etc.
util.Aspect.addBefore(Test, "getName", false, (instance: Test) => {
Instance.name="Programmer's Voice"
Console.log ("===Print log: output one log")
})
Insert function after Method
the addAfter method inserts a piece of logic after the execution of the specified class method, and the final return value is the return value after the execution of the inserted function.
Parameter Description
parameter Name | type | required | description |
targetClass | Object | yes | the specified class object. |
methodName | string | yes | the original method name. The read-only method is not supported. |
isStatic | boolean | yes | specifies whether the original method is a static method. true indicates a static method and false indicates an instance method. |
after | Function | yes | The function to insert. When the function has parameters, the first parameter is this object (if isStatic is true, the class object is targetClass; If isStatic is false, it is the instance object of the calling method), the second parameter is the return value of the original method (if the original method has no return value, it is undefined), and the remaining parameters are the parameters of the original method. Functions can also have no parameters and do not process when there are no parameters. |
Simple example
import util from '@ohos.util'
class Test {
name: string = "AbnerMing"
getName(): string {
Console.log ("==printed in method")
return this.name
}
}
@Entry
@Component
struct Index {
build() {
Column() {
Button (click)
.onClick(() => {
let test = new Test()
util.Aspect.replace(Test, "getName", false, (instance: Test) => {
Instance.name="Programmer's Voice"
Console.log ("===Print log: output one log")
Return "Programmer's Big Cry"
})
Console. log ("===append logic to get:"+test. getName())
})
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
again in the above case, we put util.Aspect.addBefore is replaced by util.Aspect.addAfter. Other logic remains unchanged. It should be noted that the final return value is the return value after the execution of the inserted function, which means that the final print is the return value of the function in addAfter. Let's look at the log:
replace function
the replace method replaces the original method of the method in the specified class with another function. After the replace interface is executed, only the replaced logic is executed, and the original function logic is not executed.
Parameter Description
parameter Name | type | required | description |
targetClass | Object | yes | the specified class object. |
methodName | string | yes | The original method name. The read-only method is not supported. |
isStatic | boolean | yes | specifies whether the original method is a static method. true indicates a static method and false indicates an instance method. |
instead | Function | yes | the function with which to replace the original method. When the function has parameters, the first parameter is this object (if isStatic is true, the class object is targetClass; If isStatic is false, it is the instance object of the calling method), and the remaining parameters are the parameters of the original method. Functions can also have no parameters and do not process when there are no parameters. |
Simple Case
import util from '@ohos.util'
class Test {
name: string = "AbnerMing"
getName(): string {
Console.log ("==printed in method")
return this.name
}
}
@Entry
@Component
struct Index {
build() {
Column() {
Button (click)
.onClick(() => {
let test = new Test()
util.Aspect.replace(Test, "getName", false, (instance: Test) => {
Instance.name="Programmer's Voice"
Console.log ("===Print log: output one log")
Return "Programmer's Big Cry"
})
Console. log ("===append logic to get:"+test. getName())
})
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
we printed a log in the getName method. When we execute the replace method, we can find that the printing was not executed because the function has been replaced and the original function logic is not executed.
Related Summary
the correct use of AOP, can improve the modularity, reusability, maintainability and flexibility of the code, while reducing the coupling, making the system easier to extend and maintain.
Subscribe to my newsletter
Read articles from AbnerMing directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
