Good APIs Are Transparent In Their Expectations And Dependencies

Posted May 9, 2012 at 9:38 AM by Ben Nadel

Tags: Javascript / DHTML

Last week, I read Maintainable JavaScript by Nicholas Zakas. One of the chapters that really struck a chord in me was that on Event Handling in a JavaScript application. Event handling, and the responsibility of event handlers, is a topic that I have struggled with in the past. In his chapter, Zakas outlines two rules for proper event handling:

  1. Separate application logic [from event logic].
  2. Don't pass the Event object around.

In the explanation for the second rule, Zakas has a sentence that seems obvious at first; but, the more I think about it, the more profound it becomes:

Good APIs are transparent in their expectations and dependencies... (Page 79 of 205)

He brings this up in the context of event handling because he argues that the Event object should never be passed around. Since the Event object may have dozens of properties, defining the Event object as a method dependency (ie. argument / parameter) doesn't really provide any insight into what properties of the Event object will be used.

If you need to access, for example, the clientX and clientY properties of the event, simply extract those from the Event object and pass them into the necessary method. This makes it completely clear what data is required by the method and creates a transparent API.

Misko Hevery (Agile Coach at Google) talks about this approach in several of his Google Tech Talks. He explains that, from a Testing standpoint, passing around only the bare minimum of what is needed creates code that is much more easily tested. And, he argues, that code that is easily tested will also be code that is much better architected.

I bring this up only as a reality-check for myself: as I am architecting my code, I should always be asking myself if I can pass less data - if I can find a way to make my methods more cohesive and more transparent.




Reader Comments

May 9, 2012 at 11:09 AM // reply »
19 Comments

In The Pragmatic Programmer, they relate this to The law of Demeter.

http://en.wikipedia.org/wiki/Law_of_Demeter

Briefly, any object should know as little about the outside world as possible (e.g. it shouldn't need to know about the many methods and properties of the 'event' object when it really only needs to get a single property from it.

Would you recommend the maintainable js book?


May 10, 2012 at 9:43 AM // reply »
11,243 Comments

@Dominic,

Thanks for the link. I've been hearing a lot about the Law of Demeter (LoD) lately with all my reading about OOP (Object Oriented Programming). Especially when dependency injection (DI) is involved.

Lots of very interesting points of view! Still trying to wrap my head around it all and bring it together into one cohesive picture. I think my doing the "Object Calisthenics" is going to help. I gotta get another one of those started ASAP.

The Maintainable JavaScript book is good, but it wasn't what I expected. I thought it was going to be more architecture-oriented, but it was more about style, formatting, syntax best-practices, and heavily about automation (building, testing, deploying).

The latter half - automation - is something I personally need a LOT Of help with. As such, the book was a good dose of reality for me who typically rocks FTP or git Push/Pull to deploy code.

Take a look at the book Table of Contents to get a sense of how it might apply to you.


May 22, 2012 at 7:12 PM // reply »
2 Comments

i've been coding javascript for 10 years or so and i'm rather new to OOP JS as well, but i totally agree with passing around as little as possible, for me it kinda like storing the length of an array as a variable for loops when we know the array length won't be changing instead of querying the array length for each iteration.

on the same line of thinking, it just seems more logical, to 'tell not ask' the object as to me it makes the object more modular when it only knows how to do what you tell it, and more direct to use since you can't ask it anything, *you* have to know what it does before using it and that should be covered in the api i.e. which methods are public - so everything becomes more like a one way conversation with each object telling the other what to do instead of asking, and it's a lot like a good business structure or the army where the person in charge tells their underling what to do, and they just do it if they can or pass it on to one of their underlings. lol.

can you provide a link that goes into more details about 'Object Calisthenics'


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 22, 2013 at 5:35 PM
Script Tags, jQuery, And Html(), Text() And Contents()
This is still an issue 2 years later. jQuery is supposed to remediate these cross browser issues, no? I have been unable to find any statement from the jQuery team calling this behavior "by de ... read »
May 22, 2013 at 12:44 PM
Ask Ben: Query Loop Inside CFScript Tags
In cf10, if you call a function that has: local.result = {}; local.result.msg = ""; local.svc = new query(); local.svc.setSQL("SELECT * FROM..."); local.obj = local.svc.exe ... read »
May 22, 2013 at 12:29 PM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben: What version of Java are you using? Also, did you test users.id to see what Java reports as the data type? I wonder if it's not a Java primitive data type, but getting returned as something ... read »
May 22, 2013 at 11:47 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Dana, Awesome - so it looks like this bug was fixed in ColdFusion 10. Thanks so much for double-checking that. ... read »
May 22, 2013 at 11:37 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
When I c&p and run on cf10, I get: Selected User IDs: 1,4 User 1 selected: YES - YES User 2 selected: NO - NO User 3 selected: NO - NO User 4 selected: YES - YES User 5 selected: NO - ... read »
May 22, 2013 at 11:27 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Tom, Good thought, but no dice. Both of these still exhibit the same behavior: users.id[ users.currentRow ] users[ "id" ][ users.currentRow ] It's just something whacky happening with ... read »
May 22, 2013 at 11:07 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
Could your problem be that "users.id" is actually an ARRAY, not a single value? Perhaps try it again with "users.id[1]" (I only have CF8 here at work). ... read »
May 22, 2013 at 7:52 AM
Nested Views, Routing, And Deep Linking With AngularJS
Hi, Just a quick thank you. As it happens, for my own purposes, the pending ui-router work being done in native angular is likely the one I'll adopt, but your exploration, code and documentation of ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools