JavaScript
Abstraction in Implementation 	

!
by Milan Adamovsky	

http://milan.adamovsky.com ◆ http://www.hardcorejs.com
Preface
• Based on personal observations	

• Spanning over 15 companies	

• Small companies to mostly enterprise	

• Not b...
Quick Exercise
Analyze
<html>	
<head>	
<title>	
This is the title of the page	
</title>	
</head>	
<body>	
<p id="main_content">	
This is ...
Analysis
• A document	

• A tree of hierarchal nodes off of root node	

• Two children nodes off of root node	

• Second c...
Overview
• Ultimate goal is to write less code	

• Increase reusability	

• Change way of thinking	

• Change way of codin...
Quick Example
Before
function resolveFirstName(person) {	
	
if (person.firstName)	
	
	
return person.firstName;	
	
else	
	
	
return "Fir...
After
function errorMessage(descriptor) {	
	
return ({	
	
	
age : "Age could not be determined",	
	
	
firstName : "First n...
Paradigms
Overloading
• One function serves multiple purposes	

• Argument signature determines function	

• Must differ by arity or...
Example
function addMethod(object, name, fn){ // addMethod - By John Resig (MIT Licensed)	
var old = object[ name ];	
obje...
Usage
var users = new Users();	

!

users.find(); // Finds all	

!

users.find("John"); // Finds users by name	

!

users....
Events
• Usually we couple an event to a function	

• Sometimes many functions to one event	

• We know what happens on an...
Coupled Binding
Click
function () {

alert(‘hello world!’);

}
Decoupled Binding
Click

Load

Greet

function () {

alert(‘hello world!’);

}
Decoupled Binding
Greet

function
function

function () {

alert(‘hello world!’);

}
OOP
• Object oriented programming	

• Base classes are usually most abstract	

• Polymorphism	

• Duck typing	

• Composit...
Procedural
joe();

function joe() {

sayHello();

}

jane();

function jane() {

sayHello();

}

function sayHello() {

al...
Object Oriented
joe = new Person();

function Person() {

this.hi = sayHello;

}

jane = new Person();

joe.hi();

jane.hi...
Example
function Person(name) {	
	
this.hi = sayHello;	
	
this.name = name;	
	
function sayHello() {	
	
	
console.log('hel...
Example
var Rifle = function () {	
	
this.reload = function () {};	
this.fire = function () { /* ... */ };	
},	

!

Cannon...
Example
var Rifle = function () {	
	
this.reload = function () {};	
this.fire = function () { /* ... */ };	
},	

!

Cannon...
MVC
• Abstraction engrained in architecture 	

• Separation of concerns (SoC)	

• Decouple model, view, controller	

• Eac...
Traditional
JS
CSS
HTML
MVC
CSS
Data

HTML
JS
Example
function controller(model, view) {	
	
var items = “";	

!

	
	
	

for (var i = 0, count = model.items.length; i < ...
RWD / AWD
• Responsive responds to screen widths	

• Adaptive adapts to devices	

• Use mobile-first approach in all code	
...
Coding
Thought Process
• Do not care for specifics	

• Do not care who calls what	

• Assume anyone can call anything	

• Assume a...
APIs
• Make them intuitive	

• Do not rely on documentation	

• Provide switches for easy customization	

• Prioritize flex...
Nomenclature
• Generalize identifiers	

• Don’t over-generalize, stay within context	

• Reverse name groupings	

• Group r...
Before
function buildPage()	
{	
	 var facebookIcon = "http://www.facebook.com/icon.png";	
	 	
	 while (someConditionIsTrue...
Improving
function buildPage()	
{	
	 var iconFacebook = "http://www.facebook.com/icon.png";	
	 	
	 while (someConditionIsT...
After
function buildPage(icons)	
{	
	 icons.facebook = "http://www.facebook.com/icon.png";	
	 	
	 while (someConditionIsTr...
Habit Forming
• Adhere to strict coding style	

• Remove comments	

• Progressively generalize identifiers	

• Identify sim...
Generalize
• This will do something	

• When something happens	

• It will take some parameters	

• Parameters will map to...
Example
function initModules()	
{	
	 for (module in app.modules) {	
	 	
if (app.modules[module].init && app.modules[module...
Considerations
• Balance performance	

• Balance maintainability	

• Strive for quality	

• Balance code base size	

• Bal...
Exercise
0
1

2

3

4

5

6

7

8

9

+

0

*

Update on button click

Gray background

White border on click
Connect
• Thank you for your time	

• Connect with me on LinkedIn	

• Join the Hardcore JavaScript community	

• Read my b...
Upcoming SlideShare
Loading in …5
×

JavaScript Abstraction

2,021 views

Published on

These are the slides for this presentation http://www.meetup.com/HardCoreJS/events/133346272/

The goal is to influence the thought process of developers and make them into rockstar engineers by showing how to form the habit of abstraction into one's coding.

Published in: Technology
  • Slide 17:
    Here we can see how much more complex it can become, but while it becomes more complex, thanks to the decoupling you can keep adding publishers and subscribers without influencing what’s already there.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Slide 16:
    Here we can see a decoupled event binding similar to a publish subscribe pattern.

    We can see that Click and Load don’t know what will happen, all they know is that something has has happened, and they are letting our code know by publishing an event. Even that event doesn’t know what it is supposed to do, only the function that knows what to do when the given event that it subscribed to is triggered.

    We don’t care what happens, all we know is we want to greet the user, but what that “greeting” consists of is lost on us.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Slide 15:
    Here we can see a simple event binding.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Slide 14:
    If we click something, we want something to happen. This in itself is already somewhat abstracted from “if we click a link, we want to go to another page”.

    It is possible to bind multiple handlers to one event. So when we click on something, we want many things to happen.

    In the two examples before, we know what will happen when. So this is what we call a “tight coupling” between events and handlers. We can “decouple” it - which is a form of abstraction.

    The way to do it is to have a DOM event (e.g. click, dblclick) trigger a handler that it trigger a custom event. The reason for this is so to abstract the effect from the cause, so any cause can trigger the effect. This means that maybe we want a handler to execute on user interaction, but maybe we want that same handler to get triggered programmatically (e.g. ajax, server push, as a result of a function, etc).

    Essentially we don’t care what happens or when it happens. All we care about is how it happens.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Slide 13:
    Here we can see how the method is the same name but depending on the number of arguments we get returned different information.

    Had we not abstracted this, then we would need to have one method for each piece of information we would want (e.g. findUserByName, findUsersByFirstLastName, etc)
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

JavaScript Abstraction

  1. 1. JavaScript Abstraction in Implementation ! by Milan Adamovsky http://milan.adamovsky.com ◆ http://www.hardcorejs.com
  2. 2. Preface • Based on personal observations • Spanning over 15 companies • Small companies to mostly enterprise • Not based on comprehensive research • Full life cycle of web development
  3. 3. Quick Exercise
  4. 4. Analyze <html> <head> <title> This is the title of the page </title> </head> <body> <p id="main_content"> This is my content </p> <ul> <li class="first"> One <li> Two <ol> <li class="first"> A </ol> <li> </ul> </body> </html>
  5. 5. Analysis • A document • A tree of hierarchal nodes off of root node • Two children nodes off of root node • Second child node has two children nodes • Two children nodes are siblings
  6. 6. Overview • Ultimate goal is to write less code • Increase reusability • Change way of thinking • Change way of coding • Anticipate future code evolution
  7. 7. Quick Example
  8. 8. Before function resolveFirstName(person) { if (person.firstName) return person.firstName; else return "First name could not be found!"; } ! function findAge(person) { return person.age; } ! function printOutName(person) { if (cookie === "senior") { findAge() + 20; resolveAddress(); } return person.lastName || "No last name was found on record!"; }
  9. 9. After function errorMessage(descriptor) { return ({ age : "Age could not be determined", firstName : "First name could not be found!", lastName : "No last name was found on record!" })[descriptor]; } ! function resolveDescriptor(descriptor) { return typeof this[descriptor] !== "undefined" ? this[descriptor] : errorMessage(descriptor); } ! function resolveSeniority() { if (cookie === "senior") { findAge() + 20; resolveAddress(); } }
  10. 10. Paradigms
  11. 11. Overloading • One function serves multiple purposes • Argument signature determines function • Must differ by arity or data types • Same function name • JavaScript can only simulate overloading
  12. 12. Example function addMethod(object, name, fn){ // addMethod - By John Resig (MIT Licensed) var old = object[ name ]; object[ name ] = function(){ if ( fn.length == arguments.length ) return fn.apply( this, arguments ); else if ( typeof old == 'function' ) return old.apply( this, arguments ); }; } function Users(){ addMethod(this, "find", function(){ // Find all users... }); addMethod(this, "find", function(name){ // Find a user by name }); addMethod(this, "find", function(first, last){ // Find a user by first and last name }); }
  13. 13. Usage var users = new Users(); ! users.find(); // Finds all ! users.find("John"); // Finds users by name ! users.find("John", "Resig"); // Finds users by first and last name ! users.find("John", "E", "Resig"); // Does nothing
  14. 14. Events • Usually we couple an event to a function • Sometimes many functions to one event • We know what happens on an event • We should not care what happens • Decouple handlers from events
  15. 15. Coupled Binding Click function () {
 alert(‘hello world!’);
 }
  16. 16. Decoupled Binding Click Load Greet function () {
 alert(‘hello world!’);
 }
  17. 17. Decoupled Binding Greet function function function () {
 alert(‘hello world!’);
 }
  18. 18. OOP • Object oriented programming • Base classes are usually most abstract • Polymorphism • Duck typing • Composition
  19. 19. Procedural joe(); function joe() {
 sayHello();
 } jane(); function jane() {
 sayHello();
 } function sayHello() {
 alert(‘hello world!’);
 }
  20. 20. Object Oriented joe = new Person(); function Person() {
 this.hi = sayHello;
 } jane = new Person(); joe.hi();
 jane.hi(); function sayHello() {
 alert(‘hello world!’);
 }
  21. 21. Example function Person(name) { this.hi = sayHello; this.name = name; function sayHello() { console.log('hello world from ' + this.name); } } ! function init(names) { var people = []; for (var i = 0, count = names.length; i < count; i++) { people.push(new Person(names[i])); } return people; } function greet(people) { for (var i = 0, count = people.length; i < count; i++) { people[i].hi(); } } greet(init(["Joe", "Jane"]));
  22. 22. Example var Rifle = function () { this.reload = function () {}; this.fire = function () { /* ... */ }; }, ! Cannon = function () { this.reload = function () {}; this.fire = function () {}; }; ! var Soldier = function (gun) { this.currentGun = gun; this.inventory = { guns : [ gun ] }; this.attack = function () { this.currentGun.fire(); }; }; ! var Tank = function (gun) { this.currentGun = gun; this.inventory = { guns : [ gun ] }; this.attack = function () { this.currentGun.fire(); }; }; ! var soldier = new Soldier( new Rifle() ), tank = new Tank( new Cannon() );
  23. 23. Example var Rifle = function () { this.reload = function () {}; this.fire = function () { /* ... */ }; }, ! Cannon = function () { this.reload = function () {}; this.fire = function () {}; }; ! var Combatant = function (gun) { this.currentGun = gun; this.inventory = { guns : [ gun ] }; this.attack = function () { this.currentGun.fire(); }; }; ! var soldier = new Combatant( new Rifle() ), tank = new Combatant( new Cannon() );
  24. 24. MVC • Abstraction engrained in architecture • Separation of concerns (SoC) • Decouple model, view, controller • Each component replaceable • Any of these can be further abstracted
  25. 25. Traditional JS CSS HTML
  26. 26. MVC CSS Data HTML JS
  27. 27. Example function controller(model, view) { var items = “"; ! for (var i = 0, count = model.items.length; i < count; i++) { items += view.item.replace("{{item}}", model.items[i]); } } return view.list.replace("{{items}}", items); ! ! var view = { item : "<li>{{item}}</li>", list : "<ul>{{items}}</ul>" }; ! var model = { items : [1, 2, 3] }; ! console.log(controller(model, view));
  28. 28. RWD / AWD • Responsive responds to screen widths • Adaptive adapts to devices • Use mobile-first approach in all code • Segment code to accommodate growth • Use lazy loaders and module patterns
  29. 29. Coding
  30. 30. Thought Process • Do not care for specifics • Do not care who calls what • Assume anyone can call anything • Assume anything can contain anything • Think interfaces not internals
  31. 31. APIs • Make them intuitive • Do not rely on documentation • Provide switches for easy customization • Prioritize flexibility and agility of code • Design functions to handle one thing
  32. 32. Nomenclature • Generalize identifiers • Don’t over-generalize, stay within context • Reverse name groupings • Group related variables in objects
  33. 33. Before function buildPage() { var facebookIcon = "http://www.facebook.com/icon.png"; while (someConditionIsTrue()){ doSomeWork(); } var i = resolveTwitterIcon(); } ! var PinterestSmallLogo = pinterest(); ! buildPage();
  34. 34. Improving function buildPage() { var iconFacebook = "http://www.facebook.com/icon.png"; while (someConditionIsTrue()){ doSomeWork(); } var iconTwitter = resolveTwitterIcon(); } ! var iconPinterest = pinterest(); ! buildPage();
  35. 35. After function buildPage(icons) { icons.facebook = "http://www.facebook.com/icon.png"; while (someConditionIsTrue()){ doSomeWork(); } icons.twitter = resolveTwitterIcon(); } ! var }; ! icons = { facebook : "", pinterest : pinterest(), twitter : "" buildPage(icons);
  36. 36. Habit Forming • Adhere to strict coding style • Remove comments • Progressively generalize identifiers • Identify similar patterns to normalize • Code in anticipation for change
  37. 37. Generalize • This will do something • When something happens • It will take some parameters • Parameters will map to some object • The outcome will be specific to context
  38. 38. Example function initModules() { for (module in app.modules) { if (app.modules[module].init && app.modules[module].checked()) { if (app.modules[module].init.call(this, arguments)) { initialized++; } } } } function initModules() { var module; for (moduleName in app.modules) { module = app.modules[moduleName]; if (module.init && module.checked()) { if (module.init.call(this, arguments)) { initialized++; } } } }
  39. 39. Considerations • Balance performance • Balance maintainability • Strive for quality • Balance code base size • Balance complexity
  40. 40. Exercise 0 1 2 3 4 5 6 7 8 9 + 0 * Update on button click Gray background White border on click
  41. 41. Connect • Thank you for your time • Connect with me on LinkedIn • Join the Hardcore JavaScript community • Read my blog • Contact me via e-mail

×