Sneak peek to Javascript AOP

This article is originally written on here on Mar 20, 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.

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.

You will find a term Cross-cutting Concern every time you search for what is AOP. It means, literally, “I think I should log at here, here and here” or “All these point, values should be validated as those are from user input”.

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 think some then().then().then() will be added and the code will be getting uglier and uglier and 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.

A code below is written according to aspect.js library example. It is more familiar to Java developers than to Javascript developers. Even if this is not familiar to you, don’t worry. It is enough if you can guess “Oh! It looks like logging after BookCollection.getNameByISBN.” This article ain’t for explaining you aspect.jslibrary. So just assume the code can be separated like this and move on. We will see how this work later this article.

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 reduced and its role looks obvious. In this way, you can gradually increase Aspect. And no matter how much Aspect is added, BookCollection will only have code for its role. In addition, note that the name pattern above can be applied to various classes and methods, given the expression /^get.*/. Even if more classes need to perform common operations, they can be applied to all of them without increasing the number of lines of code.

To explain again, we have separated logging, caching, etc. that 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 prepared for the ES7 standard. You may have already complained about the example above, I know, 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, but I do not think anyone will be brave enough to apply it to a real project. Of course, there are some libraries that can be used immediately other than aspect.js, but aspect.js is chosen because it is easy to explain and faithfully implements the AOP concept. If you want to apply AOP to something right now, you can look up meld or other libraries. However, I am a little disappointed with the options that are not much more than I thought when looking for AOP JavaScript libraries this time.

It is hard to explain everything in this short article. I will try to write only a short hint of how the Proxy + Decorator can become an 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 IEs).

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, let’s 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 in the code above, this is to show how it works and is different from the code provided by aspect.js. 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.

In the Java world, sometimes the term “Black Magic” is used to describe AOP. 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 codes seem to cross-cut the OOP rules of the Java world. If so, will it be true for the JavaScript world too? will JavaScript AOP be black magic? Given what we have, even if we do not have to introduce AOP, and even if we do not have the 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


Originally published at medium.com on March 20, 2017.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s