$30 off During Our Annual Pro Sale. View Details »

Spaghetti com amêndoas: Desenrolando seu código Javascript

Spaghetti com amêndoas: Desenrolando seu código Javascript

Aprenda a utilizar Namespaces, Module Pattern e Almond para organizar melhor seu JavaScript e construir aplicações mais sólidas e escaláveis.

Arthur Gouveia

October 03, 2015
Tweet

More Decks by Arthur Gouveia

Other Decks in Technology

Transcript

  1. Spaguetti com amêndoas
    Desenrolando seu código Javascript
    @ArthurGouveia

    View Slide

  2. - O projeto é simples…
    …na sua cabeça preguiçosa

    View Slide

  3. - É só botar uns “ífi”…
    …naquele(s) cenário(s) que você não previu

    View Slide

  4. Só o Ctrl + F para achar…
    …aquele trecho de código no arquivo de 3000 linhas

    View Slide

  5. - Reutilizar? Ctrl + C e Ctrl + V
    …pra colocar mais massa nesse Spaghetti Code

    View Slide

  6. Os antigos sábios já diziam:

    View Slide

  7. Namespaces

    Module Pattern

    Almond
    Os ingredientes que faltavam

    para desenrolar esse seu

    Spaghetti Code

    View Slide

  8. Arthur Gouveia
    Software Engineer @ Reliant Solutions

    View Slide

  9. Credits: https://commons.wikimedia.org/wiki/File:Pasta.jpg
    Namespaces
    ‘Global scope’ === ‘Danger’
    Variable/Function name overwriting
    Third-party scripts, etc

    View Slide

  10. Show me the code
    var chef = { name: 'Cuca', title: 'Mestre' };
    whoIsTheChef();
    changeChef();
    whoIsTheChef();
    function whoIsTheChef() {
    console.log(chef.title + ' ' + chef.name);
    }
    /* Random function from third-party script */
    function changeChef() {
    chef = { name: 'Benta', title: 'Dona' };
    }

    View Slide

  11. Show me the code
    > Mestre Cuca
    > Dona Benta
    var chef = { name: 'Cuca', title: 'Mestre' };
    whoIsTheChef();
    changeChef();
    whoIsTheChef();
    function whoIsTheChef() {
    console.log(chef.title + ' ' + chef.name);
    }
    /* Random function from third-party script */
    function changeChef() {
    chef = { name: 'Benta', title: 'Dona' };
    }

    View Slide

  12. Show me the code
    /* Single global object solution */
    var KitchenApp = KitchenApp || {};
    KitchenApp.chef = { name: 'Cuca', title: 'Mestre' };
    whoIsTheChef();
    changeChef();
    whoIsTheChef();
    function whoIsTheChef() {
    console.log(KitchenApp.chef.title + ' ' + KitchenApp.chef.name);
    }
    /* Random function from third-party script */
    function changeChef() {
    chef = { name: 'Benta', title: 'Dona' };
    }

    View Slide

  13. Show me the code
    > Mestre Cuca
    > Mestre Cuca
    /* Single global object solution */
    var KitchenApp = KitchenApp || {};
    KitchenApp.chef = { name: 'Cuca', title: 'Mestre' };
    whoIsTheChef();
    changeChef();
    whoIsTheChef();
    function whoIsTheChef() {
    console.log(KitchenApp.chef.title + ' ' + KitchenApp.chef.name);
    }
    /* Random function from third-party script */
    function changeChef() {
    chef = { name: 'Benta', title: 'Dona' };
    }
    Unique
    ‘use strict’ won’t allow this

    View Slide

  14. Show me the code
    /* Single global object solution + Object Literal Notation */
    var KitchenApp = KitchenApp || {};
    KitchenApp.Chef = {
    info: { name: 'Cuca', title: 'Mestre' },
    whoIsTheChef: function() {
    console.log(this.info.title + ' ' + this.info.name);
    },
    changeChef: function(chef_info) {
    this.info = chef_info;
    }
    };
    KitchenApp.Chef.whoIsTheChef();
    changeChef({ name: 'Ana Maria Braga', title: 'Dona' });
    KitchenApp.Chef.whoIsTheChef();
    KitchenApp.Chef.changeChef({ name: 'Ana Maria Braga', title: 'Dona' });
    KitchenApp.Chef.whoIsTheChef();
    /* Random function from third-party script */
    function changeChef(chef_info) { chef = chef_info; }

    View Slide

  15. Show me the code
    > Mestre Cuca
    > Mestre Cuca
    > Ana Maria Braga
    /* Single global object solution + Object Literal Notation */
    var KitchenApp = KitchenApp || {};
    KitchenApp.Chef = {
    info: { name: 'Cuca', title: 'Mestre' },
    whoIsTheChef: function() {
    console.log(this.info.title + ' ' + this.info.name);
    },
    changeChef: function(chef_info) {
    this.info = chef_info;
    }
    };
    KitchenApp.Chef.whoIsTheChef();
    changeChef({ name: 'Ana Maria Braga', title: 'Dona' });
    KitchenApp.Chef.whoIsTheChef();
    KitchenApp.Chef.changeChef({ name: 'Ana Maria Braga', title: 'Dona' });
    KitchenApp.Chef.whoIsTheChef();
    /* Random function from third-party script */
    function changeChef(chef_info) { chef = chef_info; }

    View Slide

  16. Source: http://www.freeimages.com/photo/kitchen-tools-1237100
    Module Pattern
    Single Responsibility Principle
    Privacy (clean global scope) with IIFEs
    Independency & Reusability
    Locked state

    View Slide

  17. Module
    1. a separable component, frequently one that is
    interchangeable with others, for assembly into units of
    differing size, complexity, or function.
    Source: http://dictionary.reference.com/browse/module?s=t

    View Slide

  18. Single
    Responsibility
    Principle

    View Slide

  19. Show me the code
    var ingredientsForPasta = ['Pasta', 'Water', 'Salt'];
    // IIFE - Immediately Invoked Function Expression
    var KitchenApp = (function() {
    'use strict';
    // Isolated scope with access to Global
    console.log(ingredientsForPasta);
    var ingredientsForSauce = ['Tomato', 'Olive Oil', 'Basil'];
    console.log(ingredientsForSauce);
    }());
    console.log(ingredientsForPasta);
    // Error: ingredientsForSauce is not defined
    // No access to variables defined inside de IIFE
    console.log(ingredientsForSauce);

    View Slide

  20. Show me the code
    var ingredientsForPasta = ['Pasta', 'Water', 'Salt'];
    // IIFE - Immediately Invoked Function Expression
    var KitchenApp = (function() {
    'use strict';
    // Isolated scope with access to Global
    console.log(ingredientsForPasta);
    var ingredientsForSauce = ['Tomato', 'Olive Oil', 'Basil'];
    console.log(ingredientsForSauce);
    }());
    console.log(ingredientsForPasta);
    // Error: ingredientsForSauce is not defined
    // No access to variables defined inside de IIFE
    console.log(ingredientsForSauce);
    > [ 'Pasta', 'Water', 'Salt' ]
    > [ 'Tomato', 'Olive Oil', 'Basil' ]
    > [ 'Pasta', 'Water', 'Salt' ]

    > ಠ_ಠ

    View Slide

  21. var KitchenApp = KitchenApp || {};
    KitchenApp = (function(){
    function init() {
    KitchenApp.ChefModule.init();
    KitchenApp.ChefModule.getNames();
    }
    return { init: init }
    }());
    KitchenApp.ChefModule = (function(){
    'use strict';
    var names;
    function init() { names = ['Dona Benta', 'Palmirinha', 'Ana Maria Braga']; };// public
    function getNames(){ console.log(sortChefs()); }; // public
    function setNames(chefsNames) { names = chefsNames; }; // public
    function sortChefs() { return names.sort(); } // private
    return { init: init, getNames: getNames, setNames: setNames }
    }());
    KitchenApp.init();
    Show me the code

    View Slide

  22. Show me the code
    > [ 'Ana Maria Braga', 'Dona Benta', 'Palmirinha' ]
    var KitchenApp = KitchenApp || {};
    KitchenApp = (function(){
    function init() {
    KitchenApp.ChefModule.init();
    KitchenApp.ChefModule.getNames();
    }
    return { init: init }
    }());
    KitchenApp.ChefModule = (function(){
    'use strict';
    var names;
    function init() { names = ['Dona Benta', 'Palmirinha', 'Ana Maria Braga']; };// public
    function getNames(){ console.log(sortChefs()); }; // public
    function setNames(chefsNames) { names = chefsNames; }; // public
    function sortChefs() { return names.sort(); } // private
    return { init: init, getNames: getNames, setNames: setNames }
    }());
    KitchenApp.init();

    View Slide

  23. Almond
    AMD Implementation
    Define and Require modules


    ~3kb of cool stuff
    Source: http://www.freeimages.com/photo/almonds-1317800

    View Slide

  24. Asynchronous
    Module
    Definition

    View Slide

  25. Show me the code
    define('Module.Chef', [], function() {
    var name = 'Palmirinha',
    salutation = 'Hello, AMD World.';
    function intro() {
    return 'I am ' + name + '. ' + salutation;
    }
    return {
    intro: intro
    }
    });
    define('Kitchen', ['Module.Chef'], function(chef) {
    function init() {
    console.log(chef.intro());
    }
    return {
    init: init
    }
    });
    var kitchenApp = require('Kitchen');
    kitchenApp.init();

    View Slide

  26. Show me the code
    > I am Palmirinha. Hello, AMD World.
    define('Module.Chef', [], function() {
    var name = 'Palmirinha',
    salutation = 'Hello, AMD World.';
    function intro() {
    return 'I am ' + name + '. ' + salutation;
    }
    return {
    intro: intro
    }
    });
    define('Kitchen', ['Module.Chef'], function(chef) {
    function init() {
    console.log(chef.intro());
    }
    return {
    init: init
    }
    });
    var kitchenApp = require('Kitchen');
    kitchenApp.init();

    View Slide

  27. Show me the code
    (function(){
    var spaghetti = document.body.dataset.spaghetti;
    if (spaghetti !== undefined) {
    require('Recipe.' + spaghetti).cook();
    } else {
    document.write('Y u no select a recipe?');
    }
    }());











    kitchenApp.js
    index.html

    View Slide

  28. Show me the code
    (function(){
    var spaghetti = document.body.dataset.spaghetti;
    if (spaghetti !== undefined) {
    require('Recipe.' + spaghetti).cook();
    } else {
    document.write('Y u no select a recipe?');
    }
    }());
    kitchenApp.js
    index.html





    View Slide

  29. Show me the code
    bolognese.js
    define('Recipe.Bolognese',
    [
    'Ingredients.Water',
    'Ingredients.Salt',
    'Ingredients.Pasta',
    'Ingredients.Tomato',
    'Ingredients.GroundBeef',
    'Ingredients.OliveOil'
    ], function(water, salt, pasta, tomato, groundBeef, oliveOil) {
    var cook = function() {
    addIngredients([water, salt, pasta, oliveOil]);
    makeSauce([tomato, salt, oliveOil]);
    addIngredients([groundBeef]);
    }
    var addIngredients = function(ingredients) {}
    var makeSauce = function(ingredients) {}
    return {
    cook: cook
    };
    });

    View Slide

  30. Use sua preguiça
    a favor de eficiência

    View Slide

  31. Design Patterns

    View Slide

  32. Modularize
    seu código

    View Slide

  33. Obrigado!
    @ArthurGouveia

    View Slide