Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Aspect-oriented programming
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
== Motivation and basic concepts == Typically, an aspect is ''scattered'' or ''tangled'' as code, making it harder to understand and maintain. It is scattered by the function (such as logging) being spread over a number of unrelated functions that might use ''its'' function, possibly in entirely unrelated systems or written in different languages. Thus, changing logging can require modifying all affected modules. Aspects become tangled not only with the mainline function of the systems in which they are expressed but also with each other. Changing one concern thus entails understanding all the tangled concerns or having some means by which the effect of changes can be inferred. For example, consider a banking application with a conceptually very simple method for transferring an amount from one account to another:<ref>Note: The examples in this article appear in a syntax that resembles that of the [[Java (programming language)|Java]] language.</ref> <syntaxhighlight lang="java"> void transfer(Account fromAcc, Account toAcc, int amount) throws Exception { if (fromAcc.getBalance() < amount) throw new InsufficientFundsException(); fromAcc.withdraw(amount); toAcc.deposit(amount); } </syntaxhighlight> However, this transfer method overlooks certain considerations that a deployed application would require, such as verifying that the current user is authorized to perform this operation, encapsulating [[database transaction|database transactions]] to prevent accidental data loss, and logging the operation for diagnostic purposes. A version with all those new concerns might look like this: <syntaxhighlight lang="java"> void transfer(Account fromAcc, Account toAcc, int amount, User user, Logger logger, Database database) throws Exception { logger.info("Transferring money..."); if (!isUserAuthorised(user, fromAcc)) { logger.info("User has no permission."); throw new UnauthorisedUserException(); } if (fromAcc.getBalance() < amount) { logger.info("Insufficient funds."); throw new InsufficientFundsException(); } fromAcc.withdraw(amount); toAcc.deposit(amount); database.commitChanges(); // Atomic operation. logger.info("Transaction successful."); } </syntaxhighlight> In this example, other interests have become ''tangled'' with the basic functionality (sometimes called the ''business logic concern''). Transactions, security, and logging all exemplify ''[[cross-cutting concern]]s''. Now consider what would happen if we suddenly need to change the security considerations for the application. In the program's current version, security-related operations appear ''scattered'' across numerous methods, and such a change would require major effort. AOP tries to solve this problem by allowing the programmer to express cross-cutting concerns in stand-alone modules called ''aspects''. Aspects can contain ''advice'' (code joined to specified points in the program) and ''inter-type declarations'' (structural members added to other classes). For example, a security module can include advice that performs a security check before accessing a bank account. The [[pointcut]] defines the times ([[join point]]s) when one can access a bank account, and the code in the advice body defines how the security check is implemented. That way, both the check and the places can be maintained in one place. Further, a good pointcut can anticipate later program changes, so if another developer creates a new method to access the bank account, the advice will apply to the new method when it executes. So for the example above implementing logging in an aspect: <syntaxhighlight lang="aspectj"> aspect Logger { void Bank.transfer(Account fromAcc, Account toAcc, int amount, User user, Logger logger) { logger.info("Transferring money..."); } void Bank.getMoneyBack(User user, int transactionId, Logger logger) { logger.info("User requested money back."); } // Other crosscutting code. } </syntaxhighlight> One can think of AOP as a debugging tool or a user-level tool. Advice should be reserved for cases in which one cannot get the function changed (user level)<ref>{{cite web|url=https://www.gnu.org/software/emacs/manual/html_node/elisp/Advising-Functions.html|title=gnu.org|publisher=GNU Project|access-date=5 May 2018|url-status=live|archive-url=https://web.archive.org/web/20171224053656/http://www.gnu.org/software/emacs/manual/html_node/elisp/Advising-Functions.html|archive-date=24 December 2017}}</ref> or do not want to change the function in production code (debugging).
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)