javascript abstraction

Post on 05-Dec-2014

480 Views

Category:

Technology

3 Downloads

Preview:

Click to see full reader

DESCRIPTION

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.

TRANSCRIPT

JavaScriptAbstraction 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 based on comprehensive research

• Full life cycle of web development

Quick Exercise

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>

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

Overview

• Ultimate goal is to write less code

• Increase reusability

• Change way of thinking

• Change way of coding

• Anticipate future code evolution

Quick Example

Beforefunction 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!";}

Afterfunction 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(); }}

Paradigms

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

Examplefunction 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 });}

Usagevar 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

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

Click

function () { alert(‘hello world!’); }

Coupled Binding

Decoupled Binding

Click

function () { alert(‘hello world!’); }

Greet

Load

Decoupled Binding

function () { alert(‘hello world!’); }

Greet

function

function

OOP

• Object oriented programming

• Base classes are usually most abstract

• Polymorphism

• Duck typing

• Composition

function sayHello() { alert(‘hello world!’); }

Procedural

function joe() { sayHello(); }

joe(); jane();function jane() { sayHello(); }

function sayHello() { alert(‘hello world!’); }

Object Oriented

joe.hi(); jane.hi();

joe = new Person();

jane = new Person();

function Person() { this.hi = sayHello; }

Examplefunction 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"]));

Examplevar 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() );

Examplevar 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() );

MVC

• Abstraction engrained in architecture

• Separation of concerns (SoC)

• Decouple model, view, controller

• Each component replaceable

• Any of these can be further abstracted

Traditional

HTML

CSS

JS

MVC

HTML

JS

CSS

Data

Examplefunction 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));

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

Coding

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

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

Nomenclature

• Generalize identifiers

• Don’t over-generalize, stay within context

• Reverse name groupings

• Group related variables in objects

Beforefunction buildPage() { var facebookIcon = "http://www.facebook.com/icon.png"; while (someConditionIsTrue()){ doSomeWork(); } var i = resolveTwitterIcon(); }!var PinterestSmallLogo = pinterest();!buildPage();

Improvingfunction buildPage() { var iconFacebook = "http://www.facebook.com/icon.png"; while (someConditionIsTrue()){ doSomeWork(); } var iconTwitter = resolveTwitterIcon(); }!var iconPinterest = pinterest();!buildPage();

Afterfunction buildPage(icons) { icons.facebook = "http://www.facebook.com/icon.png"; while (someConditionIsTrue()){ doSomeWork(); } icons.twitter = resolveTwitterIcon(); }!var icons = { facebook : "", pinterest : pinterest(), twitter : ""};!buildPage(icons);

Habit Forming

• Adhere to strict coding style

• Remove comments

• Progressively generalize identifiers

• Identify similar patterns to normalize

• Code in anticipation for change

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

Examplefunction 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++; } } } }

Considerations

• Balance performance

• Balance maintainability

• Strive for quality

• Balance code base size

• Balance complexity

Exercise

0

1 2 3

4 5 6

7 8 9

+ 0 *

Update on button click

White border on click

Gray background

Connect

• Thank you for your time

• Connect with me on LinkedIn

• Join the Hardcore JavaScript community

• Read my blog

• Contact me via e-mail

top related