1. Lessons from a rewrite
Rebecca Murphey • Gotham JS • New York, New York
Saturday, July 9, 2011
2. ere’s a subtle reason that programmers always
want to throw away the code and start over. e
reason is that they think the old code is a mess. ...
e reason that they think the old code is a mess
is because of a cardinal, fundamental law of
programming: It’s harder to read code than to
write it.
Joel Spolsky
Saturday, July 9, 2011
3. A content management system for the rapid
creation of content-rich mobile applications.
A PhoneGap & Dojo system that consumes the
output of the CMS to generate the application.
Saturday, July 9, 2011
5. Where a new system concept or new technology
is used, one has to build a system to throw away,
for even the best planning is not so omniscient as
to get it right the rst time. Hence plan to
throw one away; you will, anyhow.
Fred Brooks
Saturday, July 9, 2011
6. If data is required for a
route, such as node data
or the user's favorites, the
route requests the data
prior to creating the page.
Data Page Controller
Component
Component
Page Controller Component Component
Component
Component
When the app is booted
from a "cold" state (that URL Change Router Page Factory
is, it's not fast-app- Page controllers are responsible for Components are responsible for Once components are placed on the
switched), it goes receiving data from the Page Factory. Once receiving and rendering data and page, the Page Controller brokers
through a bootstrapping The Router detects a The Route asks the page the page controller receives that data, it reacting to user interaction. communication between components.
Route determines which components to display in
process. This process change in the URL, looks factory to generate a page
for a matching route in controller. If the page its postMixInProperties method and sets up Components whose content can change Components announce events either by
ensures the application "placements," which define the components during a single page view should expose publishing a topic (for events that may
toura.app.Routes, and controller is for a node, the
is working with the that will be placed on the page and the data an API using setters (i.e. have app-wide significance) or by calling
parses any additional Page Factory figures out
most recent data, and parameters out of the URL which template (Audios, that needs to be passed to them. The _setContentAttr) that allows Page a method (such as onClick). Page
also sets up various (such as the node ID, Images, etc.) the node actual instantiation and placement of Controllers to update their content. Controllers can subscribe to these
application-wide Device Storage asset type, etc.). uses. The page factory components is handled in the postCreate topics or connect to these method calls
creates an instance of the method of toura.pageControllers._Page, Alternately, a component can define an (much like connecting to events). This
functionality, including
page controller and hands which is inherited by all Page Controllers. attributeMap object that specifies how happens in the Page Controller's
the Router, UI, Page the component should react when a postCreate method.
the created instance back
Factory, Data Store, to the Route. property is set.
and several others.
Once these pieces are
in place, the app Remote
triggers a URL change
to the home node, and
the process outlined
here begins.
Every time the user goes UI
to a new page, we check
the age of the local data; if
it is more than 8 hours old,
we see whether we need
to do an over-the-air
update.
Browser
Page Container
Old Page Controller New Page Controller
Component Component
Component Component
Component Component
The Route asks toura.app.UI to place the Page Controller in the UI; in turn, toura.app.UI sets the content
attribute of the Page Container. If there is already a page on screen, the Page Container handles the animation
between the pages, and calls the destroy method of the old page, which results in the proper teardown of the old
page and its components.
Understand
what you’re rewriting
Saturday, July 9, 2011
7. Have we
no
loaded the Populate DB
bundled with bundled data
data?
yes
no
Is the remote
dfd.resolve()
reachable?
Get the remote
version
Saturday, July 9, 2011
14. Develop a
communication
manifesto
Saturday, July 9, 2011
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
Saturday, July 9, 2011
16. myComponent.set(key, val)
to change state
myComponent.on<Evt>(data)
to announce state changes
myComponent.connect(evt, handler)
to listen for events & methods
myComponent.subscribe(topic)
to react to published topics
dojo.publish(topic, data)
to announce occurrences of app-wide interest
Saturday, July 9, 2011
32. e secret to building large apps is
never build large apps. Break up your
applications into small pieces. en,
assemble those testable, bite-sized pieces
into your big application.
Justin Meyer
Saturday, July 9, 2011
33. function nodeRoute(route, nodeId, pageState) {
pageState = pageState || {};
var nodeModel = toura.app.Data.getModel(nodeId),
page = toura.app.UI.getCurrentPage();
if (!page || !page.node || nodeId !== page.node.id) {
page = toura.app.PageFactory.createPage('node', nodeModel);
page.init(pageState);
toura.app.UI.showPage(page, nodeModel);
} else {
page.init(pageState);
}
// record node pageview if it is node-only
if (nodeId && !pageState.assetType) {
dojo.publish('/node/view', [ route.hash ]);
}
return true;
}
Saturday, July 9, 2011
37. videoPlayer.set('mediaId', mediaId);
_setMediaIdAttr : function(mediaId) {
var media = this.media = this.mediasCache[mediaId];
if (this.useHtml5Player && !this.player) {
this._queuedMedia = media;
return;
}
this._queuedMedia = null;
if (this.player) {
this.player.src = media.url;
}
},
Saturday, July 9, 2011
38. It takes con dence to throw work away ...
When people rst start drawing, they’re often
reluctant to redo parts that aren’t right ...
they convince themselves that the drawing
is not that bad, really — in fact, maybe they
meant it to look that way.
Paul Graham
Saturday, July 9, 2011