Gaia/System/Refactoring Plan: Difference between revisions

Jump to navigation Jump to search
 
(17 intermediate revisions by 3 users not shown)
Line 13: Line 13:
=== Stage.1 - Painless instantiation ===
=== Stage.1 - Painless instantiation ===


Rewrite all modules to be instantiable and rewrite unit tests, as well as jsdoc. '''Everything that has states need to be an instance, even if we only need one in the app.'''
'''Everything that has states need to be an instance, even if we only need one in the app.''' Rewrite all modules to be instantiable and rewrite unit tests, as well as JSDOC.


The stage’s target is to make sure we could have the following pattern:
See [[Gaia/System/Refactoring_Plan#Stage_1_example|Stage 1 example]] for detail.


bootstrap.js (starting point, simply one-liner)
There are already bugs (87 bugs, excluding downloadmananger and fxaccounts for now. Take as you like!) of this stage for every js under the system app. See meta bug.
 
<pre>


// (we need to expose the system instance because test atoms need to call some functions directly)
==== Initialization ====
window.system = new System();
window.system.start();


</pre>
'''We should not change where we initialize the instance of the module in this stage.''' We do this in Stage 1 to ensure we don't don't need to resolve the launching sequence puzzle for now. If the module your are dealing with simply start itself, feel free to add
 
system.js (the "root" of the all modules, starts the "world")


<pre>
<pre>


var System = function System() {
   /**
   /* some initial states */
  * Start ourselves
  this.started = false;
  * XXX: To be moved.
};
  */
System.prototype.start = function() {
   window.foo = new Foo();
  this.started = true;
   window.foo.start();
 
  /* modules */
   this.appWindowFactory = new AppWindowFactory(this);
   this.appWindowManager = new AppWindowManager(this);
  this.screenManager = new ScreenManager(this);
 
  /* event listeners */
};
 
.. other prototype methods follows ..


</pre>
</pre>


'''(TBD: jsdocs)'''
at the bottom of the file. If the module is initialized elsewhere, e.g. <code>bootstrap.js</code>, you can still safely do that there.
 
'''Caveat''': Please take care of instantiation timing and dependency. Please ensure the rewrite does not break anything (run tests!). A pair of <code>init()</code>/<code>start()</code> and <code>uninit()</code>/<code>stop()</code> function is recommended to give the instance an explicit start and finish.
 
With this pattern we are able to do unit test anywhere,
and there's no architecture design involved in this stage.
Even a new employee could take one of the modules to rewrite it correctly.


There are already bugs (87 bugs, excluding downloadmananger and fxaccounts for now. Take as you like!) of this stage for every js under the system app. See meta bug.
'''Note'''
* You are required to resolve jshint errors in this stage and remove the file from blacklist.
* You are required to have unit tests in this stage.
* If you register any event listener in start(), '''remember to remove them in stop()'''. Otherwise, our unit tests will get confused because we run all unit tests in the same iframe and module dependencies will mess things up. For the self-initialized script, do call the <code>stop()</code> method on the "global" instance in the test <code>setup()</code>.


=== Stage.2 - Architecture love ===
=== Stage.2 - Architecture love ===
==== Find out loading sequence and dependency relationships ====
==== Find out loading sequence and dependency relationships ====
1. File bugs to track all dependency resolving.
==== Do architecture review and rework case by case ====
==== Do architecture review and rework case by case ====
# Find the unnecessary module coupling and remove it.
# Find the unnecessary module coupling and remove it.
Line 95: Line 78:
</pre>
</pre>
and jsdoc will be generated to 'docs' folder
and jsdoc will be generated to 'docs' folder
=== Stage 1 example ===
<pre>
'use strict';
(function(exports) {
  /**
  * DESCRIPTION-OF-THIS-MODULE.
  * @class Module
  */
  function Module() {
  }
  Module.prototype = {
    /**
    * DESCRIPTION-OF-IMPORTANT-PUBLIC-API
    * @memberof Module.prototype
    */
    show: function(data) {
      /**
        * DESCRIPTION-OF-THE-EVENT.
        * @event Module#i-am-displayed
        */
      this.publish('i-am-displayed');
    },
    /**
    * DESCRIPTION-OF-WHAT-START-DO
    * @memberof Module.prototype
    */
    start: function() {
      if (this._started) {
        throw 'Module XXX have already started.';
      }
      this._started = true;
      window.addEventListener('someevent', this);
    },
    /**
    * DESCRIPTION-OF-WHAT-STOP-DO
    * @memberof Module.prototype
    */
    stop: function() {
      if (!this._started) {
        throw 'Module XXX have not started.';
      }
      this._started = false;
      window.removeEventListener('someevent', this);
    },
    /**
    * DESCRIPTION-OF-EVENT-HANDLER
    * @memberof Module.prototype
    */
    handleEvent: function(evt) {
    },
    /**
    * DESCRIPTION-OF-IMPORTANT-PUBLIC-ATTRIBUTE
    * @memberof Module.prototype
    */
    state: 'begin'
  };
  exports.Module = Module;
}(window));
</pre>
[[File:jsdoc-sample.png|300px|thumb|left|Output with default theme]]
Confirmed users
478

edits

Navigation menu