Workshop 2: JavaScript Design Patterns

Post on 14-Jan-2017

451 views 2 download

transcript

Javascript Design Patterns. AMD & commonJS.

RequireJS

Marc Torrent Vernetta

Javascript Design Patterns

A reusable solution that can be applied to commonly occurring problems

in software design -in our case- in writing JavaScript Web application.

What is a Pattern?

Templates for how we solve problems - ones which can be used in quite

a few different situations situations

Addy Osmani

Three Main Benefits

1. Proven Solutions2. Easily Reused3. Expressive

NOT EXACT SOLUTIONS SUPPORT DEVELOPERS

A Good Pattern

1. Solves a particular problem2. Not an obvious solution3. A proven described concept4. Describe a relationship

Display some recurring phenomenon:

❖ Fitness of purpose❖ Usefulness❖ Applicability

Antipatterns

1. Polluting global namespace2. Strings to setTimeout and setInterval + eval()3. Modify the Object prototype (very bad!!)4. Javascript in an inline form5. Use of document.write

Knowledge for anti-patterns is critical for success !!!!

Antipatterns

1. Polluting global namespace2. Strings to setTimeout and setInterval + eval()3. Modify the Object prototype (very bad!!)4. Javascript in an inline form5. Use of document.write

Knowledge for anti-patterns is critical for success !!!!

Design Pattern Types

➢ Creational○ Factory Pattern○ Constructor Pattern○ Singleton Pattern○ Prototype Pattern

➢ Structural○ Module Pattern○ Adapter Pattern○ Decorator Pattern○ Façade Pattern○ Mixin Pattern○ Flyweight Pattern

➢ Behavioral○ Mediator Pattern○ Observer Pattern

- Classes

- Objects

Creational Patterns

Constructor Pattern

Constructor Pattern - Prototype

Prototype Pattern

Sub-Classing

Mixin Pattern

Structural Patterns

Module Pattern - Object Literal

Module Pattern - IIFE

Module Pattern - Revealing

Behavioral Patterns

Observer Pattern - I

SUBJECT STATE

OBSERVERS LIST

OBSERVER OBSERVER OBSERVER OBSERVER OBSERVER

N O T I F Y

CONCRETE SUBJECT

CONCRETEOBSERVER

UPDATEUPDATEUPDATEUPDATEUPDATE

Observer Pattern - II

Observer Pattern - III

Observer Pattern - IV

Observer Pattern - V

Observer Pattern - VI

Observer Pattern - VII

Publish/Subscribe Pattern - I

PUBLISHER(SUBJECT)

SUBSCRIBER

EVENT AGGREGATOR

SUBSCRIBER SUBSCRIBER

Publish/Subscribe Pattern II

Publish/Subscribe Pattern III

Publish/Subscribe Pattern IV

Mediator Pattern - I

SUBJECT

SUBSCRIBER

EVENT AGGREGATOR

SUBSCRIBER SUBSCRIBER

MEDIATOR

Mediator Pattern - II

Mediator Pattern - III

Mediator Pattern - IV

Mediator Pattern - V

Modern Modular JavaScript Design Patterns

Module A Module B Module C Module N…...

Application

- Modular Application- Loosely Coupled

- Dependency Control- Script Loader

➢ BROWSER:- Asynchronous

Module Definition (AMD)

- requireJS➢ SERVER:

- commonJS

Dependency Control

AMD Modules

➢ Defining modules with dependencies to other modules.➢ The module and dependencies can be asynchronously

loaded.➢ Both modules are asynchronous and highly flexible by

nature➢ Removes the tight coupling between code and module

identity

AMD Modules Advantages

● Provides a clear proposal for how to approach defining flexible modules.

● Significantly cleaner than the present global namespace and <script> tag solutions many of us rely on. There's a clean way to declare stand-alone modules and dependencies they may have.

● Module definitions are encapsulated, helping us to avoid pollution of the global namespace.

● Most AMD loaders support loading modules in the browser without a build process.

● Provides a "transport" approach for including multiple modules in a single file.

● It's possible to lazy load scripts if this is needed.

AMD Modules - define vs require

define(

module_id /*optional*/,

[dependencies] /*optional*/,

definition function /*function for instantiating the

module or object*/

);

require(

[dependencies] /*required*/,

complete function /*function for instantiating the

dependecies*/

);

AMD Modules - define vs require

define([“url_to_anonymous_module”, “named_module_id”],

function(ModuleA, ModuleB) {

function doCoolStuff(a) {

ModuleA.cool(a, ModuleB.getCool());

}

return {

cool: doCoolStuff

};

}

);

require([“myModule”], function(moduleC) {

var superCool = “super cool”;

moduleC.cool(superCool);

});

requireJS

➢ Library for working with AMD modules. Asynchronous script loader and dependency manager.

➢ Easy naming definition with a json configuration. Prepare non AMD modules for other AMD modules as its dependency management stays untouched.

➢ Optimization tool for bundling modules in one or many optimized, uglified and minimized module.

➢ With plugin extension for loading non JS scripts, like CSS, JSON, JSONP, etc…

➢ commonJS wrapper for styling AMD module loading with commonJS syntax and reducing verbosity.

requireJS and AMD

require([dependencies], function(depA, depB, ...){});

requirejs([dependencies], function(depA, depB, ...){});

define() function and module definition remains exactly the same

requirejs.config({

baseUrl: ‘path_to_where_scripts_are’,

paths: {

name_of_a_module: ‘relative_path_of_the_module’,

other_module_name: ‘relative_path_of_other_module’

},

shim: {

name_of_a_module: {

exports: ‘Foo’,

},

other_module_name: [“name_of_a_module”]

}

});

requireJS and HTML

<html>

<head></head>

<body>

<script data-main="js/app.js"

src="js/require.js"></script>

<script type=”text/javascript”>

requirejs([“app”], function(app) {

app.start();

});

</script>

</body>

</html>

commonJS modules

➢ Reusable piece of JavaScript which exports specific objects made available to any dependent code.

➢ Unlike AMD, there are typically no function wrappers around such modules.

➢ Two primary parts: a free variable named exports which contains the objects a module wishes to make available to other modules and a require function that modules can use to import the exports of other modules

➢ Only able to define objects which can be tedious to work with if we're trying to obtain constructors out of them

➢ Useful for Server side because it can use io, fs, system, etc..

commonJS in depth

var libA = require(‘package/libA’),

libB = require(‘package/libB’);

function foo(){

libA.log( ‘hello world!’ );

}

exports.foo = foo;

exports.bar = function bar() {

libB.myFunc();

};

var foobar = require(‘foobar’);

foobar.foo();

foobar.bar();

requireJS with commonJS style

define(function(require) {

var moduleA = require(‘moduleA’),

moduleB = require(‘moduleB’);

function doCoolStuff(a) {

moduleA.cool(a, moduleB.getCool());

}

return {

cool: doCoolStuff

};

}

);

Library App with RequireJS & AMD

Thanks for your attention!Leave your questions on the comments section