What is the Aspect-Oriented Programming anyway?
Have you tried searching for Aspect-Oriented Programming on Google? If you search for AOP and read them, soon you will find the term Cross-cutting Concern in all articles. The term may not be familiar with you. Think of logging which is a typical example. You can say “I should log at here, here and here too”. Regardless of the context of any class or function, it crosscuts all with a concern called logging.
Logging and Object-Oriented Programming Problem
Let’s look at an example below. I wrote a “hello world” AOP use case example. It is a simple code which gets
book name from
Now I want to log every time the function is called. And It’ll be better if it can handle the request from cache. Oh! and don’t forget to validate the
ISBN as the value is from user input. Our work as a developer won’t finish simply. How will the code change if we add codes for caching, validating and so on?
I added logging from the initial implementation. And I guess some
then().then().then() will be added. The code will be getting uglier and uglier. I won’t write an example for this :(. I am disappointed with my code, sitting in front of my laptop watching the code gets longer and uglier. I just wanted to get a book name. How come the work so complicate? Is the
BookCollection class name right one? How can I fix this?
Find one reason to change and take everything else out of the class.
Reminding what uncle bob said, Let’s try to separate it into several classes.
Hm… It’s better. But is this really the best? Sure we can make it better with the power of OOP. But eventually, we will end up with creating long class names and complex inheritances.
BookCollection.getNameByISBN . We will see how this work later this article. So just assume the code can be separated like this and move on.
BookCollection class looks cleaner! It focuses on getting data. And logging resides on separated class. This time let’s do the same for the caching job too.
Yey! The irrelevant code in
BookCollection has been removed completely and the role looks obvious. In this way, you can gradually add aspects. And no matter how much the aspects are added,
BookCollection will remain focused on its own work.
And one more thing to say, note that the name pattern above can be applied to various classes and methods, given the expression
/^get.*/. Even if additional classes need to perform common operations, aspects can be applied to all of them without increasing the number of lines of code.
To explain again, we have separated logging, caching from original complex code. Those correspond to Cross-cutting Concern of Collection classes. At this point, if you are wondering if this code is really working this way, go to aspect.js and follow the example. And don’t forget Babel and Decorator plugin.
Decorators are being ready for the ES7 standard. Some of you may have already complained about the example above. Yes, the library depends on decorators that are not yet standard (TC39 Notes, July 28 2016, Implement new decorator proposal when finalized). You can follow the example using the Babel Legacy Decorator plugin.(Do not hurry to apply it to a production project). Of course, there are some alternative libraries. But I choose aspect.js because it shows the AOP concept well. If you want to apply AOP to something right now, you can look up the meld or other libraries too.
The above code creates a Proxy of the
BookCollection prototype and executes the log only when a function of the given pattern is executed. If you are not familiar with Proxy, I recommend that you read the article “ES6 Features — 10 Use Cases for Proxy”. Now, let’s change the code by adding Decorators to bind the Logger and BookClass.
Don’t panic about
@wove above is exactly the same code as the code below.
If you want to understand a little more about Descriptors, read Decorators, Decorators, and functions. Decorators are on the Stage2 Draft, and there are many discussions in the current standard. So, please consider that there is room for future changes. Back to the code above, I wrote it to show you how it works and it is not how aspect.js works. If you understand how it works so far, I think it would be enough to imagine how the code I introduced with AOP would work.
Originally published at medium.com on March 20, 2017.