SlideShare a Scribd company logo
1 of 49
Download to read offline
Functionality-Focused Code Organization
             Rebecca Murphey • @rmurphey • rebeccamurphey.com
             jQuery Boston 2010


Saturday, October 16, 2010
Saturday, October 16, 2010
Saturday, October 16, 2010
object laterals literals
                module pattern
                revealing module pattern
                etc.

Saturday, October 16, 2010
Saturday, October 16, 2010
$('#search').submit(function(e) {
                               e.preventDefault();
                               resultsContainer.empty();

                              var term = $(this).find('input').val();
                              if (!$.trim(term)) { return; }

                              $.each(['search.news', 'search.web'], function(i, svcName) {
                                $.getJSON(
                                  searchUrl,
                                  { q : buildQuery(term, svcName), format : 'json' },

                                   function(resp) {
                                     $('<li><h3>' + svcName + '</h3><ul></ul></li>')
                                       .appendTo(resultsContainer)
                                       .find('ul')
                                       .html(
                                         $.map(resp.query.results.result, function(r) {
                                           return Mustache.to_html(resultsTpl, r);
                                         }).join('')
                                       );
                                   }
                                 );
                               });
                             });




              a “traditional” jQuery way of solving the problem
Saturday, October 16, 2010
what happens when the spec evolves?




Saturday, October 16, 2010
Saturday, October 16, 2010
Saturday, October 16, 2010
is the codebase suitable for collaboration?




Saturday, October 16, 2010
$('#search').submit(function(e) {
                      e.preventDefault();
                      resultsContainer.empty();

                       var term = $(this).find('input').val();
                       if (!$.trim(term)) { return; }

                       $.each(['search.news', 'search.web'], function(i, svcName) {
                         $.getJSON(
                           searchUrl,
                           { q : buildQuery(term, svcName), format : 'json' },

                          function(resp) {
                             $('<li><h3>' + svcName + '</h3><ul></ul></li>')
                               .appendTo(resultsContainer)
                               .find('ul')
                               .html(
                                 $.map(resp.query.results.result, function(r) {
                                    return Mustache.to_html(resultsTpl, r);
                                  }).join('')
                               );
                           }
                        );
                      });
                    });




Saturday, October 16, 2010
is it testable?




Saturday, October 16, 2010
$('#search').submit(function(e) {
                      e.preventDefault();
                      resultsContainer.empty();

                       var term = $(this).find('input').val();
                       if (!$.trim(term)) { return; }

                       $.each(['search.news', 'search.web'], function(i, svcName) {
                         $.getJSON(
                           searchUrl,
                           { q : buildQuery(term, svcName), format : 'json' },

                          function(resp) {
                             $('<li><h3>' + svcName + '</h3><ul></ul></li>')
                               .appendTo(resultsContainer)
                               .find('ul')
                               .html(
                                 $.map(resp.query.results.result, function(r) {
                                    return Mustache.to_html(resultsTpl, r);
                                  }).join('')
                               );
                           }
                        );
                      });
                    });



              how to test all of the important pieces of this?
Saturday, October 16, 2010
is it readable & maintainable?




Saturday, October 16, 2010
“Writing to be read means writing code ... with
                the idea that someone else will read it. is fact
                alone will make you edit and think of better
                ways to solve the problem you have at hand.”
                                        Stoyan Stefanov, “JavaScript Patterns”



Saturday, October 16, 2010
maintainable code is ...
                             readable
                             consistent
                             predictable
                             looks like one person wrote it
                             documented



Saturday, October 16, 2010
$('#search').submit(function(e) {
                      e.preventDefault();
                      resultsContainer.empty();

                       var term = $(this).find('input').val();
                       if (!$.trim(term)) { return; }

                       $.each(['search.news', 'search.web'], function(i, svcName) {
                         $.getJSON(
                           searchUrl,
                           { q : buildQuery(term, svcName), format : 'json' },

                          function(resp) {
                             $('<li><h3>' + svcName + '</h3><ul></ul></li>')
                               .appendTo(resultsContainer)
                               .find('ul')
                               .html(
                                 $.map(resp.query.results.result, function(r) {
                                    return Mustache.to_html(resultsTpl, r);
                                  }).join('')
                               );
                           }
                        );
                      });
                    });




Saturday, October 16, 2010
// NAVIGATION
                 function togglePage(section) {
                   // if the clicked section is already the current section AND we're in full page mode
                   // minimize the current tab
                   if (jQuery('#md_tab_'+ section).hasClass('current') && jQuery('#md_tab_'+ section + ' a').hasClass('md_fullpage')) {
                     // alert('clicked section is current section AND fullpage mode is active; teaser should load');
                   // Minimize
                     jQuery('#md_tabs_navigation a').removeClass('md_fullpage');
                     jQuery('.md_body').hide();
                     jQuery('#md_feature').slideDown('normal',function(){
                       var bodyContent = jQuery('#md_body_'+ section);
                       bodyContent.fadeOut('normal',function(){
                         jQuery('#md_tabs_navigation a').each(function(){
                           var thisSection = jQuery(this).html().replace('<span<','').replace('</span<','');
                           var thisSection_comp = thisSection.toLowerCase().replace(' ','_');
                            jQuery('#md_body_'+ thisSection_comp).load(
                              '/app/modules/info/loadTeaser.php?sect='+ thisSection_comp,
                              function(){
                                  tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox');
                                  bodyContent.animate({ height: 'toggle', opacity: 'toggle' },"slow");
                               }
                            );
                         });
                       });
                     });
                     jQuery('#expandtabs span').empty().append('Expand Tabs');
                   } else {
                   // if the clicked section is NOT the current section OR we're NOT in full page mode
                   // then let's go to full page mode and show the whole tab
                   // Maximize
                     // alert('clicked section is not the current section OR full page mode is not active; full section should load');
                     jQuery('#md_tabs_navigation li').removeClass('current');
                     jQuery('#md_tab_'+ section).addClass('current');
                     jQuery('#md_tabs_navigation a').addClass('md_fullpage');
                     jQuery('.md_body').hide();
                     jQuery('#md_feature').slideUp('normal',function(){
                       var bodyContent = jQuery('#md_body_'+ section);
                       bodyContent.fadeOut('normal',function(){
                         bodyContent.empty();
                         var pageLoader = 'info/loadSection.php?sect='+ section;
                         if (section == 'contact_us') {
                             pageLoader = 'contact/loadContactForm.php?form_id=1';
                         }
                         bodyContent.load('/app/modules/'+ pageLoader,function(){
                           // ADD THICKBOXES
                            tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox');
                           $recent_news_links = jQuery('ul.md_news li a.recent_news_link');
                           $recent_news_links
                               .unbind('click')
                               .each(function(){
                                 var hrefMod = this.href;
                                  hrefMod = hrefMod.replace(/article/,'loadNews').replace(/storyid/,'id');
                                 this.href = hrefMod;
                               })
                               .click(function(){
                                 var t = this.title || this.name || null;
                                 var a = this.href || this.alt;
                                 var g = this.rel || false;
                                  tb_show(t,a,g);
                                 this.blur();
                                 return false;
Saturday, October 16, 2010 });
(By the way, buy this book.)




Saturday, October 16, 2010
Saturday, October 16, 2010
When the heavy lifting of manipulating,
                displaying, and interacting with data falls
                to the browser, it makes sense to reconsider
                the typical DOM-centric approach.




Saturday, October 16, 2010
there’s a better way*
                             *lots of them, in fact. this is one.




Saturday, October 16, 2010
Functionality-focused code organization
                means identifying the pieces of functionality in
                your application and teasing them apart.


Saturday, October 16, 2010
diversion: pubsub 101
                             like custom events, but without the overhead!




Saturday, October 16, 2010
$('input.magic').click(function(e) {
                   // publish a "topic" when something happens
                   $.publish('/something/interesting', [ e.target.value ]);
                 });

                 // register our interest in knowing when something happens
                 $.subscribe('/something/interesting', function(val) {
                   alert(val);
                 });




              a simple pubsub example
Saturday, October 16, 2010
$('input.magic').click(function(e) {
                   $(document).trigger('/something/interesting', [ this.value ]);
                 });

                 $(document).bind('/something/interesting', function(e, val) {
                   alert(val);
                 });




              pubsub with custom events works too
Saturday, October 16, 2010
In jQuery itself, $.fn.ajaxStart and
                $.fn.ajaxStop basically let you subscribe to
                topics published by jQuery’s underlying
                Ajax code.




Saturday, October 16, 2010
diversion: require.def
                                      possibly my new favorite thing
                             (also a great tool for this modularization stuff)




Saturday, October 16, 2010
require.def() De nes a function to be run
                when the module is included. e function can
                return a value, but it doesn’t have to. If
                dependencies are speci ed, they’re available to
                the function as arguments.




Saturday, October 16, 2010
pattern: object Returns an object, though
                the de nition function can close other
                variables that won’t be visible outside the
                function.




Saturday, October 16, 2010
require.def(function() {
                   var privateThing = 'myPrivateThing',

                             privateObj = {
                               maxLength : 5,

                               setPrivateThing : function(val) {
                                 if (val.length > this.maxLength) {
                                   console.log('TOO MUCH');
                                   return;
                                 }

                                 privateThing = val;
                               },

                               otherMethod : function() {
                                  console.log(privateThing);
                                }
                             };

                   return {
                      setPrivateThing : $.proxy(privateObj, 'setPrivateThing'),
                      publicMethod : $.proxy(privateObj, 'otherMethod')
                   };
                 });




              closes private vars, returns a public API
Saturday, October 16, 2010
pattern: factory Returns a function, that,
                when called, returns an instance of an object
                that is de ned inside the module. e factory
                function may optionally bake in instance
                property options or overrides. e base object
                is not exposed publicly.




Saturday, October 16, 2010
require.def(function(){
                   var Person = {
                     intro : 'My name is ',
                     outro : '. You killed my father. Prepare to die.',

                       speak : function() {
                          console.log(
                            this.intro,
                            this.firstName,
                            this.lastName,
                            this.outro
                          );
                        }
                     };

                   return function(config) {
                     return $.extend(Object.create(Person), {
                        firstName : config.firstName,
                        lastName : config.lastName
                      });
                   };
                 });



              returns a “factory” for creating Person instances
Saturday, October 16, 2010
Functionality-focused code organization
                means identifying the pieces of functionality in
                your application and teasing them apart.


Saturday, October 16, 2010
mediators
                views
                services




Saturday, October 16, 2010
Saturday, October 16, 2010
• user submits
                             search input   search form
                                            • user input is
                                            validated
                                            • if input is valid,
                                            the search service is
                              searcher
                                            contacted

                              searcher      • when the search
                                            service returns
                                            results, they are
                                            displayed in the
                                            results container

                               results




Saturday, October 16, 2010
• sets up views and services
         search input view                                  • brokers communication
                                                            between views and services
      • sets up search input form
      • listens for user to submit
      search form                                                 search page
      • verifies form data
                                                                   mediator
      • announces the user’s search
      if it is valid (non-empty)




               results view
      • provides an API for
      mediators to add results and
      clear the results container
      • listens for user interaction
      with results and broadcasts
                                          searcher service                            results service
      information about it to be
      handled by the mediator                                                     • provides an API for
                                          searcher service                        mediators to use to register
                                                                                  user interaction with results,
                                                                                  and to get information about
                                       • provides an API for                      those interactions later
                                       mediators to communicate
                                       with
                                       • performs searches and pre-
                                       processes results into a
                                       consistent format
                                       • accepts callback to allow
                                       results to be used by mediator


Saturday, October 16, 2010
mediators set up views and services, and
                broker communications between them,
                eliminating the need for direct communication




Saturday, October 16, 2010
views display data, observe user input, and
                broadcast messages that mediators can react
                to; may also provide an API for updating data




Saturday, October 16, 2010
views in our sample application
Saturday, October 16, 2010
services manage data & state, exposing a
                limited public API for mediators




Saturday, October 16, 2010
• sets up views and services
         search input view                                  • brokers communication
                                                            between views and services
      • sets up search input form
      • listens for user to submit
      search form                                                 search page
      • verifies form data
                                                                   mediator
      • announces the user’s search
      if it is valid (non-empty)




               results view
      • provides an API for
      mediators to add results and
      clear the results container
      • listens for user interaction
      with results and broadcasts
                                          searcher service                            results service
      information about it to be
      handled by the mediator                                                     • provides an API for
                                          searcher service                        mediators to use to register
                                                                                  user interaction with results,
                                                                                  and to get information about
                                       • provides an API for                      those interactions later
                                       mediators to communicate
                                       with
                                       • performs searches and pre-
                                       processes results into a
                                       consistent format
                                       • accepts callback to allow
                                       results to be used by mediator


Saturday, October 16, 2010
user requests page

                                                                                    app mediator

                                                                                             app mediator hands
                                                                                             request to appropriate
                                                                                             page mediator



                                 page mediator sets up                              page mediator
                             views that will be required
                                            for the page

                                                                                             page mediator sets up
                                                                                             services that will be required
                                                                                             for the page
                                                              views and services
                                                           DO NOT communicate
                                                                         directly




                         view                                                          service


                         view                                                          service


                         view                                                          service


Saturday, October 16, 2010
sample app
                             http://github.com/rmurphey/ffco




Saturday, October 16, 2010
Saturday, October 16, 2010
mediators
                app mediator, page mediator
                views
                message, recent searches, search input, results
                services
                searchers, results


Saturday, October 16, 2010
MOAR FEATURES PLZ?
                indicate search term in URL
                persist recent searches across page reloads
                tabbed search results view
                improve the code I didn’t show you




Saturday, October 16, 2010
rebeccamurphey.com

                             blog.rebeccamurphey.com

                             @rmurphey

                             http://github.com/rmurphey/ffco

                             http://spkr8.com/t/4650

                             http://pinboard.in/u:rmurphey/t:ffco/




Saturday, October 16, 2010

More Related Content

What's hot

jQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyjQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyHuiyi Yan
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeRebecca Murphey
 
Cleaner, Leaner, Meaner: Refactoring your jQuery
Cleaner, Leaner, Meaner: Refactoring your jQueryCleaner, Leaner, Meaner: Refactoring your jQuery
Cleaner, Leaner, Meaner: Refactoring your jQueryRebecca Murphey
 
Kick start with j query
Kick start with j queryKick start with j query
Kick start with j queryMd. Ziaul Haq
 
jQuery Fundamentals
jQuery FundamentalsjQuery Fundamentals
jQuery FundamentalsGil Fink
 
Write Less Do More
Write Less Do MoreWrite Less Do More
Write Less Do MoreRemy Sharp
 
Learning jQuery in 30 minutes
Learning jQuery in 30 minutesLearning jQuery in 30 minutes
Learning jQuery in 30 minutesSimon Willison
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony AppsKris Wallsmith
 
jQuery 1.7 Events
jQuery 1.7 EventsjQuery 1.7 Events
jQuery 1.7 Eventsdmethvin
 
jQuery Namespace Pattern
jQuery Namespace PatternjQuery Namespace Pattern
jQuery Namespace PatternDiego Fleury
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuerysergioafp
 
Prototype & jQuery
Prototype & jQueryPrototype & jQuery
Prototype & jQueryRemy Sharp
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mockingKonstantin Kudryashov
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScriptAndrew Dupont
 
Intro to Advanced JavaScript
Intro to Advanced JavaScriptIntro to Advanced JavaScript
Intro to Advanced JavaScriptryanstout
 

What's hot (20)

jQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyjQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journey
 
Jquery Fundamentals
Jquery FundamentalsJquery Fundamentals
Jquery Fundamentals
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery Code
 
Cleaner, Leaner, Meaner: Refactoring your jQuery
Cleaner, Leaner, Meaner: Refactoring your jQueryCleaner, Leaner, Meaner: Refactoring your jQuery
Cleaner, Leaner, Meaner: Refactoring your jQuery
 
jQuery
jQueryjQuery
jQuery
 
Kick start with j query
Kick start with j queryKick start with j query
Kick start with j query
 
jQuery Fundamentals
jQuery FundamentalsjQuery Fundamentals
jQuery Fundamentals
 
Write Less Do More
Write Less Do MoreWrite Less Do More
Write Less Do More
 
Learning jQuery in 30 minutes
Learning jQuery in 30 minutesLearning jQuery in 30 minutes
Learning jQuery in 30 minutes
 
Bacbkone js
Bacbkone jsBacbkone js
Bacbkone js
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
jQuery 1.7 Events
jQuery 1.7 EventsjQuery 1.7 Events
jQuery 1.7 Events
 
jQuery Namespace Pattern
jQuery Namespace PatternjQuery Namespace Pattern
jQuery Namespace Pattern
 
Matters of State
Matters of StateMatters of State
Matters of State
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuery
 
Prototype & jQuery
Prototype & jQueryPrototype & jQuery
Prototype & jQuery
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
 
Intro to Advanced JavaScript
Intro to Advanced JavaScriptIntro to Advanced JavaScript
Intro to Advanced JavaScript
 

Similar to Functionality Focused Code Organization

Creating an Uber Clone - Part XVIII - Transcript.pdf
Creating an Uber Clone - Part XVIII - Transcript.pdfCreating an Uber Clone - Part XVIII - Transcript.pdf
Creating an Uber Clone - Part XVIII - Transcript.pdfShaiAlmog1
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs偉格 高
 
Desenvolvendo Aplicativos Sociais com Rails 3
Desenvolvendo Aplicativos Sociais com Rails 3Desenvolvendo Aplicativos Sociais com Rails 3
Desenvolvendo Aplicativos Sociais com Rails 3Carlos Brando
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsJarod Ferguson
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretssmueller_sandsmedia
 
Ast transformations
Ast transformationsAst transformations
Ast transformationsHamletDRC
 
Working With JQuery Part1
Working With JQuery Part1Working With JQuery Part1
Working With JQuery Part1saydin_soft
 
Security Challenges in Node.js
Security Challenges in Node.jsSecurity Challenges in Node.js
Security Challenges in Node.jsWebsecurify
 
Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7Paulo Morgado
 
Monads in javascript
Monads in javascriptMonads in javascript
Monads in javascriptJana Karceska
 
jQuery: out with the old, in with the new
jQuery: out with the old, in with the newjQuery: out with the old, in with the new
jQuery: out with the old, in with the newRemy Sharp
 
Gta v savegame
Gta v savegameGta v savegame
Gta v savegamehozayfa999
 

Similar to Functionality Focused Code Organization (20)

The jQuery Divide
The jQuery DivideThe jQuery Divide
The jQuery Divide
 
Creating an Uber Clone - Part XVIII - Transcript.pdf
Creating an Uber Clone - Part XVIII - Transcript.pdfCreating an Uber Clone - Part XVIII - Transcript.pdf
Creating an Uber Clone - Part XVIII - Transcript.pdf
 
jQuery
jQueryjQuery
jQuery
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs
 
Desenvolvendo Aplicativos Sociais com Rails 3
Desenvolvendo Aplicativos Sociais com Rails 3Desenvolvendo Aplicativos Sociais com Rails 3
Desenvolvendo Aplicativos Sociais com Rails 3
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 
Php functions
Php functionsPhp functions
Php functions
 
Working With JQuery Part1
Working With JQuery Part1Working With JQuery Part1
Working With JQuery Part1
 
Security Challenges in Node.js
Security Challenges in Node.jsSecurity Challenges in Node.js
Security Challenges in Node.js
 
JQuery introduction
JQuery introductionJQuery introduction
JQuery introduction
 
Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7
 
Hw09 Hadoop + Clojure
Hw09   Hadoop + ClojureHw09   Hadoop + Clojure
Hw09 Hadoop + Clojure
 
Hadoop + Clojure
Hadoop + ClojureHadoop + Clojure
Hadoop + Clojure
 
Monads in javascript
Monads in javascriptMonads in javascript
Monads in javascript
 
jQuery: out with the old, in with the new
jQuery: out with the old, in with the newjQuery: out with the old, in with the new
jQuery: out with the old, in with the new
 
Gta v savegame
Gta v savegameGta v savegame
Gta v savegame
 

More from Rebecca Murphey

Getting Started with Mulberry
Getting Started with MulberryGetting Started with Mulberry
Getting Started with MulberryRebecca Murphey
 
DojoConf: Building Large Apps
DojoConf: Building Large AppsDojoConf: Building Large Apps
DojoConf: Building Large AppsRebecca Murphey
 
Lessons from-a-rewrite-gotham
Lessons from-a-rewrite-gothamLessons from-a-rewrite-gotham
Lessons from-a-rewrite-gothamRebecca Murphey
 

More from Rebecca Murphey (6)

Getting Started with Mulberry
Getting Started with MulberryGetting Started with Mulberry
Getting Started with Mulberry
 
Introducing Mulberry
Introducing MulberryIntroducing Mulberry
Introducing Mulberry
 
DojoConf: Building Large Apps
DojoConf: Building Large AppsDojoConf: Building Large Apps
DojoConf: Building Large Apps
 
Lessons from-a-rewrite-gotham
Lessons from-a-rewrite-gothamLessons from-a-rewrite-gotham
Lessons from-a-rewrite-gotham
 
Lessons from a Rewrite
Lessons from a RewriteLessons from a Rewrite
Lessons from a Rewrite
 
Modern JavaScript
Modern JavaScriptModern JavaScript
Modern JavaScript
 

Recently uploaded

TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxfnnc6jmgwh
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkPixlogix Infotech
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 

Recently uploaded (20)

TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App Framework
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 

Functionality Focused Code Organization

  • 1. Functionality-Focused Code Organization Rebecca Murphey • @rmurphey • rebeccamurphey.com jQuery Boston 2010 Saturday, October 16, 2010
  • 4. object laterals literals module pattern revealing module pattern etc. Saturday, October 16, 2010
  • 6. $('#search').submit(function(e) { e.preventDefault(); resultsContainer.empty(); var term = $(this).find('input').val(); if (!$.trim(term)) { return; } $.each(['search.news', 'search.web'], function(i, svcName) { $.getJSON( searchUrl, { q : buildQuery(term, svcName), format : 'json' }, function(resp) { $('<li><h3>' + svcName + '</h3><ul></ul></li>') .appendTo(resultsContainer) .find('ul') .html( $.map(resp.query.results.result, function(r) { return Mustache.to_html(resultsTpl, r); }).join('') ); } ); }); }); a “traditional” jQuery way of solving the problem Saturday, October 16, 2010
  • 7. what happens when the spec evolves? Saturday, October 16, 2010
  • 10. is the codebase suitable for collaboration? Saturday, October 16, 2010
  • 11. $('#search').submit(function(e) { e.preventDefault(); resultsContainer.empty(); var term = $(this).find('input').val(); if (!$.trim(term)) { return; } $.each(['search.news', 'search.web'], function(i, svcName) { $.getJSON( searchUrl, { q : buildQuery(term, svcName), format : 'json' }, function(resp) { $('<li><h3>' + svcName + '</h3><ul></ul></li>') .appendTo(resultsContainer) .find('ul') .html( $.map(resp.query.results.result, function(r) { return Mustache.to_html(resultsTpl, r); }).join('') ); } ); }); }); Saturday, October 16, 2010
  • 12. is it testable? Saturday, October 16, 2010
  • 13. $('#search').submit(function(e) { e.preventDefault(); resultsContainer.empty(); var term = $(this).find('input').val(); if (!$.trim(term)) { return; } $.each(['search.news', 'search.web'], function(i, svcName) { $.getJSON( searchUrl, { q : buildQuery(term, svcName), format : 'json' }, function(resp) { $('<li><h3>' + svcName + '</h3><ul></ul></li>') .appendTo(resultsContainer) .find('ul') .html( $.map(resp.query.results.result, function(r) { return Mustache.to_html(resultsTpl, r); }).join('') ); } ); }); }); how to test all of the important pieces of this? Saturday, October 16, 2010
  • 14. is it readable & maintainable? Saturday, October 16, 2010
  • 15. “Writing to be read means writing code ... with the idea that someone else will read it. is fact alone will make you edit and think of better ways to solve the problem you have at hand.” Stoyan Stefanov, “JavaScript Patterns” Saturday, October 16, 2010
  • 16. maintainable code is ... readable consistent predictable looks like one person wrote it documented Saturday, October 16, 2010
  • 17. $('#search').submit(function(e) { e.preventDefault(); resultsContainer.empty(); var term = $(this).find('input').val(); if (!$.trim(term)) { return; } $.each(['search.news', 'search.web'], function(i, svcName) { $.getJSON( searchUrl, { q : buildQuery(term, svcName), format : 'json' }, function(resp) { $('<li><h3>' + svcName + '</h3><ul></ul></li>') .appendTo(resultsContainer) .find('ul') .html( $.map(resp.query.results.result, function(r) { return Mustache.to_html(resultsTpl, r); }).join('') ); } ); }); }); Saturday, October 16, 2010
  • 18. // NAVIGATION function togglePage(section) { // if the clicked section is already the current section AND we're in full page mode // minimize the current tab if (jQuery('#md_tab_'+ section).hasClass('current') && jQuery('#md_tab_'+ section + ' a').hasClass('md_fullpage')) { // alert('clicked section is current section AND fullpage mode is active; teaser should load'); // Minimize jQuery('#md_tabs_navigation a').removeClass('md_fullpage'); jQuery('.md_body').hide(); jQuery('#md_feature').slideDown('normal',function(){ var bodyContent = jQuery('#md_body_'+ section); bodyContent.fadeOut('normal',function(){ jQuery('#md_tabs_navigation a').each(function(){ var thisSection = jQuery(this).html().replace('<span<','').replace('</span<',''); var thisSection_comp = thisSection.toLowerCase().replace(' ','_'); jQuery('#md_body_'+ thisSection_comp).load( '/app/modules/info/loadTeaser.php?sect='+ thisSection_comp, function(){ tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox'); bodyContent.animate({ height: 'toggle', opacity: 'toggle' },"slow"); } ); }); }); }); jQuery('#expandtabs span').empty().append('Expand Tabs'); } else { // if the clicked section is NOT the current section OR we're NOT in full page mode // then let's go to full page mode and show the whole tab // Maximize // alert('clicked section is not the current section OR full page mode is not active; full section should load'); jQuery('#md_tabs_navigation li').removeClass('current'); jQuery('#md_tab_'+ section).addClass('current'); jQuery('#md_tabs_navigation a').addClass('md_fullpage'); jQuery('.md_body').hide(); jQuery('#md_feature').slideUp('normal',function(){ var bodyContent = jQuery('#md_body_'+ section); bodyContent.fadeOut('normal',function(){ bodyContent.empty(); var pageLoader = 'info/loadSection.php?sect='+ section; if (section == 'contact_us') { pageLoader = 'contact/loadContactForm.php?form_id=1'; } bodyContent.load('/app/modules/'+ pageLoader,function(){ // ADD THICKBOXES tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox'); $recent_news_links = jQuery('ul.md_news li a.recent_news_link'); $recent_news_links .unbind('click') .each(function(){ var hrefMod = this.href; hrefMod = hrefMod.replace(/article/,'loadNews').replace(/storyid/,'id'); this.href = hrefMod; }) .click(function(){ var t = this.title || this.name || null; var a = this.href || this.alt; var g = this.rel || false; tb_show(t,a,g); this.blur(); return false; Saturday, October 16, 2010 });
  • 19. (By the way, buy this book.) Saturday, October 16, 2010
  • 21. When the heavy lifting of manipulating, displaying, and interacting with data falls to the browser, it makes sense to reconsider the typical DOM-centric approach. Saturday, October 16, 2010
  • 22. there’s a better way* *lots of them, in fact. this is one. Saturday, October 16, 2010
  • 23. Functionality-focused code organization means identifying the pieces of functionality in your application and teasing them apart. Saturday, October 16, 2010
  • 24. diversion: pubsub 101 like custom events, but without the overhead! Saturday, October 16, 2010
  • 25. $('input.magic').click(function(e) { // publish a "topic" when something happens $.publish('/something/interesting', [ e.target.value ]); }); // register our interest in knowing when something happens $.subscribe('/something/interesting', function(val) { alert(val); }); a simple pubsub example Saturday, October 16, 2010
  • 26. $('input.magic').click(function(e) { $(document).trigger('/something/interesting', [ this.value ]); }); $(document).bind('/something/interesting', function(e, val) { alert(val); }); pubsub with custom events works too Saturday, October 16, 2010
  • 27. In jQuery itself, $.fn.ajaxStart and $.fn.ajaxStop basically let you subscribe to topics published by jQuery’s underlying Ajax code. Saturday, October 16, 2010
  • 28. diversion: require.def possibly my new favorite thing (also a great tool for this modularization stuff) Saturday, October 16, 2010
  • 29. require.def() De nes a function to be run when the module is included. e function can return a value, but it doesn’t have to. If dependencies are speci ed, they’re available to the function as arguments. Saturday, October 16, 2010
  • 30. pattern: object Returns an object, though the de nition function can close other variables that won’t be visible outside the function. Saturday, October 16, 2010
  • 31. require.def(function() { var privateThing = 'myPrivateThing', privateObj = { maxLength : 5, setPrivateThing : function(val) { if (val.length > this.maxLength) { console.log('TOO MUCH'); return; } privateThing = val; }, otherMethod : function() { console.log(privateThing); } }; return { setPrivateThing : $.proxy(privateObj, 'setPrivateThing'), publicMethod : $.proxy(privateObj, 'otherMethod') }; }); closes private vars, returns a public API Saturday, October 16, 2010
  • 32. pattern: factory Returns a function, that, when called, returns an instance of an object that is de ned inside the module. e factory function may optionally bake in instance property options or overrides. e base object is not exposed publicly. Saturday, October 16, 2010
  • 33. require.def(function(){ var Person = { intro : 'My name is ', outro : '. You killed my father. Prepare to die.', speak : function() { console.log( this.intro, this.firstName, this.lastName, this.outro ); } }; return function(config) { return $.extend(Object.create(Person), { firstName : config.firstName, lastName : config.lastName }); }; }); returns a “factory” for creating Person instances Saturday, October 16, 2010
  • 34. Functionality-focused code organization means identifying the pieces of functionality in your application and teasing them apart. Saturday, October 16, 2010
  • 35. mediators views services Saturday, October 16, 2010
  • 37. • user submits search input search form • user input is validated • if input is valid, the search service is searcher contacted searcher • when the search service returns results, they are displayed in the results container results Saturday, October 16, 2010
  • 38. • sets up views and services search input view • brokers communication between views and services • sets up search input form • listens for user to submit search form search page • verifies form data mediator • announces the user’s search if it is valid (non-empty) results view • provides an API for mediators to add results and clear the results container • listens for user interaction with results and broadcasts searcher service results service information about it to be handled by the mediator • provides an API for searcher service mediators to use to register user interaction with results, and to get information about • provides an API for those interactions later mediators to communicate with • performs searches and pre- processes results into a consistent format • accepts callback to allow results to be used by mediator Saturday, October 16, 2010
  • 39. mediators set up views and services, and broker communications between them, eliminating the need for direct communication Saturday, October 16, 2010
  • 40. views display data, observe user input, and broadcast messages that mediators can react to; may also provide an API for updating data Saturday, October 16, 2010
  • 41. views in our sample application Saturday, October 16, 2010
  • 42. services manage data & state, exposing a limited public API for mediators Saturday, October 16, 2010
  • 43. • sets up views and services search input view • brokers communication between views and services • sets up search input form • listens for user to submit search form search page • verifies form data mediator • announces the user’s search if it is valid (non-empty) results view • provides an API for mediators to add results and clear the results container • listens for user interaction with results and broadcasts searcher service results service information about it to be handled by the mediator • provides an API for searcher service mediators to use to register user interaction with results, and to get information about • provides an API for those interactions later mediators to communicate with • performs searches and pre- processes results into a consistent format • accepts callback to allow results to be used by mediator Saturday, October 16, 2010
  • 44. user requests page app mediator app mediator hands request to appropriate page mediator page mediator sets up page mediator views that will be required for the page page mediator sets up services that will be required for the page views and services DO NOT communicate directly view service view service view service Saturday, October 16, 2010
  • 45. sample app http://github.com/rmurphey/ffco Saturday, October 16, 2010
  • 47. mediators app mediator, page mediator views message, recent searches, search input, results services searchers, results Saturday, October 16, 2010
  • 48. MOAR FEATURES PLZ? indicate search term in URL persist recent searches across page reloads tabbed search results view improve the code I didn’t show you Saturday, October 16, 2010
  • 49. rebeccamurphey.com blog.rebeccamurphey.com @rmurphey http://github.com/rmurphey/ffco http://spkr8.com/t/4650 http://pinboard.in/u:rmurphey/t:ffco/ Saturday, October 16, 2010