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

How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
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
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
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
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
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
 

Recently uploaded (20)

How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
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
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
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
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
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...
 

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