45
© 2013 SpringOne 2GX. All rights reserved. Do not distribute without permission. AOP-ing your JavaScript Brian Cavalier / @briancavalier SpringJS at Pivotal / cujoJS Co-lead 1

AOP-ing your JavaScript

Embed Size (px)

DESCRIPTION

Speaker: Brian Cavalier Loose coupling. Your web front-end has that, right? Your JavaScript is using pubsub, event emitters, and message buses! Guess again, you can do better. Aspect Oriented Programming (AOP) is a technique for augmenting the behavior of objects, methods, and functions non-invasively. AOP adds new behaviors and modifies existing behaviors "from the outside". Using AOP, it's possible to create connections between components without either having any knowledge of the other and without any extra library dependencies in your code. While you may be familiar with AOP in Spring, you may not yet have applied it in JavaScript. In this talk, we'll do just that. We'll introduce simple techniques for applying AOP in pure JavaScript using no additional libraries, and then look at meld.js (https://github.com/cujojs/meld), the AOP library that powers Cujo.js (http://cujojs.com). We'll work from simple examples of making connections between components to more sophisticated examples that integrate pubsub, message buses, etc. in a truly loosely coupled way.

Citation preview

Page 1: AOP-ing your JavaScript

© 2013 SpringOne 2GX. All rights reserved. Do not distribute without permission.

AOP-ing your JavaScriptBrian Cavalier / @briancavalier

SpringJS at Pivotal / cujoJS Co-lead

1

Page 2: AOP-ing your JavaScript

Aspect Oriented Programming

AOP refresherHow to do it in JavaScript (hint: it’s easy)Application composition

2

Page 3: AOP-ing your JavaScript

AOP• Program transformation that combines separate, and possibly

unrelated, concerns• Huh?

33

Page 4: AOP-ing your JavaScript

AOP• Non-invasively augment or modify the behavior of existing

code• AOP is a composition strategy• “Advice” is a common approach

–before, around, afterReturning, afterThrowing, after

44

Page 5: AOP-ing your JavaScript

Stereotypical AOP Examples• Logging• Profiling• Transaction boundaries• Security

55

Page 6: AOP-ing your JavaScript

Composition strategies• Inheritance• Delegation• AOP

66

Page 7: AOP-ing your JavaScript

Composition strategies• Add profiling to all instances of class X

–Using inheritance breaks the “is-a” mental model–Using inheritance means changing the code that creates

instances of X to create instances of ProfiledX–Using either delegation or inheritance -> must account for profiling

code in unit tests!• Add profiling to all instances of classes X, Y, and Z

–Multiply all above problems by 3

77

Page 8: AOP-ing your JavaScript

Composition strategies• AOP can apply behavior from the outside• controlled - guarantees about not breaking your stuff• non-invasive - without changing the source code

88

Page 9: AOP-ing your JavaScript

Typical AOP approaches• Can require some sophisticated machinery• Source code transformation• Byte code transformation• Language-level Proxies• VM or runtime support

99

Page 10: AOP-ing your JavaScript

AOP in JavaScript

10

Page 11: AOP-ing your JavaScript

AOP in JavaScript• JavaScript doesn’t have Proxies*, byte code access, or VM

level support for AOP• Source code transformation• AST transformation• Or something easier ...

11

* ECMAScript 6 will have language-level Proxies

11

Page 12: AOP-ing your JavaScript

Method replacement// Save the original functionvar orig = thing.method;

// Replace it with one that does what we wantthing.method = function() { doAdditionalStuff(); return orig.apply(this, arguments);}

1212

Page 13: AOP-ing your JavaScript

Method replacementvar orig = thing.method;

thing.method = function() { try { return orig.apply(this, arguments); } catch(e) { doAdditionalStuff(e); throw e;

}};

1313

Page 14: AOP-ing your JavaScript

Method replacement• Pros

–Easy to implement–Dynamic - add and remove advice at runtime

• Cons–Changes the hasOwnProperty landscape–Harder to do app-wide weaving (e.g. classpath scanning and

global pointcuts)

1414

Page 15: AOP-ing your JavaScript

Examples• Logging

–https://github.com/briancavalier/aop-s2gx-2013/blob/master/examples/logging.js

• Profiling–https://github.com/briancavalier/aop-s2gx-2013/blob/master/

examples/around.js• Memoization

–https://github.com/briancavalier/aop-s2gx-2013/blob/master/examples/around.js#L170

1515

Page 16: AOP-ing your JavaScript

If it’s so easy ...• why isn’t it more common in JS?

–Don't know AOP exists–Apply AOP without knowing it–Know about AOP, but don't know how to apply it in JS

1616

Page 17: AOP-ing your JavaScript

AOP in JavaScript• AOP in 50 LOC - https://github.com/briancavalier/aop-

s2gx-2013/tree/master/src• cujoJS’s meld - https://github.com/cujojs/meld• Dojo’s dojo/aspect - http://dojotoolkit.org• Twitter Flight - http://twitter.github.io/flight/) -• javascript-hooker - https://github.com/cowboy/javascript-

hooker)• dcl - https://github.com/uhop/dcl

1717

Page 18: AOP-ing your JavaScript

Neato, but yawn• Guess what? Users don’t actually care about logging,

profiling, or memoization.• If that’s all we could do, this would be lame

1818

Page 19: AOP-ing your JavaScript

Can we ...• use this kind of approach to connect more interesting things

together?• What about Views, Controllers, Models, or any application

components?

1919

Page 20: AOP-ing your JavaScript

Application composition• Connecting reusable components together to make a

particular application• Now that sounds useful• It also sounds a lot like AOP: "composing units of behavior"

2020

Page 22: AOP-ing your JavaScript

Let’s make a simple app

22

Product List Shopping Cart

22

Page 23: AOP-ing your JavaScript

Let’s make a simple app

23

Product List Shopping Cart

Mediator

23

Page 24: AOP-ing your JavaScript

Let’s make a simple app

24

Product List Shopping Cart

Mediator

24

Page 25: AOP-ing your JavaScript

Let’s make a simple app• Delegation - https://github.com/briancavalier/aop-s2gx-2013/

blob/master/demo-app/vanilla• Events - https://github.com/briancavalier/aop-s2gx-2013/blob/

master/demo-app/events• Pubsub - https://github.com/briancavalier/aop-s2gx-2013/

blob/master/demo-app/pubsub

2525

Page 26: AOP-ing your JavaScript

Coupled

26

Product List Shopping CartMediator

26

Page 27: AOP-ing your JavaScript

Inseparable

27

Product ListShopping Cart

Mediator

27

Page 28: AOP-ing your JavaScript

Noooooo!

28

Other Thing

This Thing That Thing

Other Thing

Product ListShopping Cart

Mediator

Other Thing

This Thing That Thing

Other Thing

This ThingThat Thing

Other Thing

That Thing

That ThingThis Thing

Other Thing

This Thing That Thing

Other Thing

28

Page 29: AOP-ing your JavaScript

Bad• Components coupled directly to each other, or directly to a

connection lib API, or both.

2929

Page 30: AOP-ing your JavaScript

Bad• Lots of mocking to unit test• Components easily break one another• Adding new components -> changing source code of existing

components• Changing one component may require

–updating many mocks–re-unit testing all components!

3030

Page 31: AOP-ing your JavaScript

Application Composition

31

Page 32: AOP-ing your JavaScript

Application composition• The act of connecting components together to make a

complete application• Often a separate, and very different activity than

implementing the stuff inside components

3232

Page 33: AOP-ing your JavaScript

Composition plan• A dedicated place to compose application components• It owns the lines in your box and line diagrams• Example: Spring Application Context

3333

Page 34: AOP-ing your JavaScript

Composition plan

34

Composition Plan

Product List Shopping Cart

Mediator

34

Page 35: AOP-ing your JavaScript

Composition plan• Let’s re-make our app using AOP and composition• Simple AOP - https://github.com/briancavalier/aop-s2gx-2013/

blob/master/demo-app/aop-simple• meld AOP - https://github.com/briancavalier/aop-s2gx-2013/

blob/master/demo-app/aop-meld

3535

Page 36: AOP-ing your JavaScript

Good• Components have no knowledge of each other

–unit tests are easy, less mocking• Change the plan w/o changing the components' source

–no need to re-run unit tests• Add new behavior to existing applications

–minimize regressions• Create a new plan (i.e. app variant) easily

–build faster

3636

Page 37: AOP-ing your JavaScript

Composition• If we're always connecting components in similar ways, can

we create a DSL to do it?

3737

Page 38: AOP-ing your JavaScript

Yes• Let’s re-make our simple app again• cujoJS 1 (w/Controller) - https://github.com/briancavalier/aop-

s2gx-2013/tree/master/demo-app/cujojs-1• cujoJS 2 (Controller-less) - https://github.com/briancavalier/

aop-s2gx-2013/tree/master/demo-app/cujojs-2

3838

Page 39: AOP-ing your JavaScript

AOP• Add/modify behavior• Compose components• Controlled, non-invasive• Don't need a lib, but they help!

3939

Page 40: AOP-ing your JavaScript

Application composition• Separate connection from components• Make a composition plan• Test & refactor components easily• Reduce collateral damage• Build faster

4040

Page 43: AOP-ing your JavaScript

Links - Application composition• cujoJS wire - http://github.com/cujojs/wire• Other JS IOC containers popping up recently

4343

Page 44: AOP-ing your JavaScript

Links - Examples• Examples from this talk - http://github.com/briancavalier/aop-

s2gx-2013• cujoJS.com - http://cujojs.com• cujoJS sample apps - http://know.cujojs.com/samples

4444

Page 45: AOP-ing your JavaScript

Learn More. Stay Connected.

Talk to us on Twitter: @springcentralFind session replays on YouTube: spring.io/video

45