Agile: the basics

 

Core values:

Individuals and interactions over processes and tools

Working software over comprehensive documentation

Customer collaboration over contract negociation

Respond to change over following a plan.

Notice the word “over”, not “instead of”

At its core:

1) Plan and release small iterations.

2) At the end of each iteration cycle, there should be a full set of testing and verification of what was released. Ideally continuous integration and automated testing.

3) Every day progress is measure to see if small iteration goals are to be made.

4) Your product manager should be the coordinator / director / bottleneck. He must be constantly checking progress / resources / trends / grooming the backlog / re-prioritization / leading in the right direction

5) Plan / Do / Check / Act. Imagine a cannon arm, where you have to constantly adjust the angle until you hit the target.

6) Always organize a retrospective at the end of each cycle: it is important to evaluate the work done / take corrective action / adjust.

7) Project division:

Phase 1: Build the simplest system span of neccesary, barebone features first

Phase 2: Corner cases / security / flexibility / other important things on top of bare bone features

Phase 3: Refine UI / bells and whistles, secondary features, nice to haves, etc

8) Release objectives: Quality, Speed to Market, Features (number of), Brand, Reputation. Unfortunately, each one of those areas takes time and sometimes cancel each other out, so you have to balance out which ones you are to pursue first in the time given. Or if you want it all, plan a high amount of time accordingly. Or make a plan B for the ones you won’t meet.

9) Constantly prune and groom your backlog, with the following (changing) dimension in consideration at all times:

– Vision (the grandiose high level idea that will deliver you to the promised land)

– Themes (formalizing the direction towards the vision, you may have more than one theme / path to make it happen)

– Narratives (Describe your theme. high level summary of your product or service, and how it will “get you there”)

– Epics (The narrative, translated to high level features)

– Stories (Breaking down the high level features in small increment tasks and sub-features. Must be doable within one sprint, or broken down further if they don’t fit)

Type of sprints:

Push sprints: points to be burned are pre-planned and preset. They can be checked against a burn chart at the end of the sprint.

Pull sprits: kanban. The back log is maintained to have the highest items that need to be taken care of on top of the list. Developers pull the items from the top as they become available to work on them. Items sit on the following categories: Ready, In Progress, Ready for Verification, Done

Incremental vs Iterative approaches.

– Incremental: you add complete features to the product, one a a time. Riskier because you may get too close to release date with a few key features not even started.

– Iterative: you work mostly in the most important features, but make sure you also build the secondary stories, enough to reduce the risk of an entire section of your product becoming all of a sudden a must-have and you haven’t start it. Or spending a lot of time in a section where at the end won’t be as important as expected at the beginning, in which case, abandoning it won’t be such a loss

 

Other considerations:

– Collective wisdom: at estimation time, the more input you have, the more accurate the estimate is (bell curve, mean indicates the best approximation to the right answer)

– Failure does not mean bad resource / employees, but inability to lead them in the right direction. As long as there is the trust where they are willing to succeed, it should be a matter of coaching them and leading them into that. At the end of the day, who really wants to fail?

– In software development, there will always be a high amount of uncertainty about how long the project will take. Which will be reduced as you work along. Have that into consideration, and plan accordingly

– You don’t have to finish a product through to validate if it will deliver you to your company vision and objectives. Try to validate your vision / themes / epics / features as fast as possible, way ahead of release date. Sometimes you don’t have to build a complete finish product to see nobody will use it. Get early feedback. Put out alphas and betas. Mock features and measure the click-through rates to them. Validate your vision before it is too costly to readjust it or abandon it.

Javascript basics: script tag

Attributes:

type: The language your script is in. Defaults to javascript since HTML5. In older browsers you were able to run alt languages, like VBScript in IE. In fact, it is supposed to actually point to the mime type of your script. The syntax is, for example: type=”text/javascript”

language: not used. Deprecated.

async: When set to true, makes the download of the script asynchronous, not holding the page hostage until it downloads. The default is false, so pages have to wait until this downloads before they go on. It is HTML5 supported. Moving scripts at the end of the page is a more compatible technique (with older browsers) to avoid scripts blocking page rendering, but don’t do it if you have document.write commands in your script. (async=”async”)

defer: waits until the DOM is ready before executing the script. It is HTML5 supported. It is overriden by async (defer=”defer”)

XHTML compatibility. If you use that as your doctype, you have to envelop your inline scripts in CDATA, to avoid special characters like & to cause problems:

<script type="text/javascript">
//<![CDATA[
  // Your javascript here
//]]>
</script>
Example of dynamically adding scripts to a document:
var script = document.createElement("script");
script.setAttribute("src", url);
document.head.appendChild(script);

Backbone.js coding style and best practices

Stating the obvious:

1) Try to use hash tagging and history to connect disparate views as much: you keep them independent from each other this way, and back button compatible. In other words: don’t spawn views programmatically, let the router do the work for you.

2) As much as you can: one view = one template = one model and / or one collection.

3) If your page logic or functionality is too complex to accomplish the above: divide and conquer. Create sub views attached to a manager view, and break down and distribute down the logic that way to the sub-views. Your code per file will be small and manageable this way, and your complexity per view will be simpler, and easier to test and debug. Better to end up with 20 views attached to a main view, than a huge single view loaded with methods and functionality.

4) Beating on the dead horse above: atomize, atomize, atomize. Divide your view in the lowest denomination of packed functionality. That way you can encapsulate events / methods better

5) Associate a model to collections, so the conversion of backend data happens automatically (don’t build collections with no models or default models)

6) If you rerender, before you call html(), call empty(). It will clean up memory from the objects you won’t use anymore. Example: $(this.el).empty().html(mymodel.toJSON());

Backbone.js: event aggregation and AMD

Great pattern to decouple your modules, and still have clean mechanism to communicate between them.

1) Create a generic “Notifier” module:

define([
‘underscore’,
‘backbone’
], function(_, Backbone) {
var notifier = _.extend({}, Backbone.Events);
return notifier;
});

2) In the two + views or models that you want to connect, include the notifier via your AMD arguments:

define([‘jquery’,’underscore’,’backbone’,’notifier’], function ($,_,Backbone,Notifier) {

}

3) Once your notifier is included that way, to subscribe and listen to events, all you have to do now is bind to the events you would like to listen to:

initialize: function () {
Notifier.on(‘helloEvent’, function (e) { alert(‘The main view says: ‘ + e)}, this)
},

4) To trigger events and push them to the notifier (from other modules), you just have to trigger them:

events: {
“click .clickme”: “sendEventOut”
},
sendEventOut: function () {
Notifier.trigger(‘helloEvent’,’I said hello’);
}

That’s it! Now two different views (or models, or collections) can communicate back and forth via triggered events, and even pass arguments between them.