A Sneak peek to Javascript AOP
✂️

A Sneak peek to Javascript AOP

@March 17, 2017

As of last week, one of my co-workers has translated an article about ES6 Proxy. Soon after I read that, I came up with an idea about JavaScript AOP(Aspect Oriented Programming). I talked to myself, Is there anyone who talk about it? How’s it going on in JavaScript world? Here I share what I found and explain how Proxy is related to AOP.

What is the Aspect-Oriented Programming anyway?

Actually, AOP is not the hot issue in JavaScript world at least for now. And I guess many of front-end developers are not familiar with the term. So let’s start with just “AOP“, not the “Javascript AOP“.

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 BookCollection by ISBN.

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.

So… does AOP make this code better?

A code below is written according to aspect.js library example.This article ain’t for explaining you aspect.jslibrary. But I’ll use this as a demonstration. It is more familiar to Java developers than to Javascript developers. Even if this is not familiar to you, don’t worry. All you have to do is trust me that It logs after BookCollection.getNameByISBN . We will see how this work later this article.  So just assume the code can be separated like this and move on.

It looks cleaner! The BookCollection focus on getting data. And logging resides on separated class. This time let’s add CacheAspect 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

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 2016Implement 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.

How do I come up with Proxy?

It is hard to explain everything in this short article. I will just try to write only a short hint of how the “Proxy + Decorator = AOP” in Javascript. Do you remember that I mentioned Proxy is AOP’s related topic at the beginning of the article? Below is a code that mimics how the AOP Advice works by using a Proxy. ES6 Proxies and Classes are currently implemented in modern browsers, so copy and paste them into the browser as follows (no IE).

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 using Decorators to bind the Logger and BookClass.

Don’t panic about @wove Decorators. @wove above is exactly the same code as the code below.

If you want to understand a little more about Descriptors, read DecoratorsDecorators, 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.

Final words

In the Java world, sometimes AOP is called “Black Magic”. In an interview with eWeek, James Gosling described AOP “Its fraught with all kinds of problems.”, “giving folks chainsaws without instructions.” I think this is because the AOP seems to crosscut the OOP rules of the Java world. If so, will it be true for the JavaScript world too? will JavaScript AOP be the black magic too? Given what we have, even if there is no AOP, and even if there are no tools like AspectJ, we may already be wielding a more outrageous laser blade. Considering what AspectJ needs to do to apply Aspect to Java code, the JavaScript code below is easy and natural (even if you think it is dangerous).

Considering the direction of the ES6 and ES7 standards, and the popularity of Typescript and etc, JavaScript is becoming more and more like an OOP, a tool we are familiar with. As time goes, I think that there will be more talk about AOP as a supplementary to OOP. Or maybe the nature of JavaScript does not need AOP. This article is at the introductory level, so if you have any ideas on this topic, please share your thoughts. I will try to think a little more and share my thoughts again if I have any other thoughts.

References