The Javascript Pyramid Model, gather classes into a Pyramid and seal it up forever

The builders of the pyramids were killed and buried within the pyramid as an early form of architectural design  encapsulation.
So shall it be with Javascript.

Problem: your program has 30 classes in an unstructured mess.
Solution: gather related classes into sealed "Pyramids", forcing strict structure upon your unruly code.

Here I present the Pyramid model, each Javascript Class is surrounded by stone, and the occupants are forced to communicate by radio. Stone is an anonymous closure, radio is a pubsub. When a constructor is called, its last act is to delete its own scope.
  1. Organises your classes into privately scoped groups "Pyramids"
  2. Nothing outside a Pyramid may access anything inside the Pyramid, the Pyramids are loosely coupled.
  3. Each Pyramid publishes selected methods so that other Pyramids may subscribe to them.
  4. One line of code per class, and one line per Pyramid.

Here we have an "Pyramid Object" that represents the constructors for a group of classes.
 models = {Model: null, Scenario: null, Turret: null, Targets: null, GunRange: null}, 
Each null is replaced with the real class constructor when it is declared.

controllers = {Clicks: null, Controller: null, Events: null},  
Our "controllers" Pyramid Object is composed of the class constructors for Clicks, Controller and Events.

This organises our classes into 2 "Pyramid Object" packages, "models" and "controllers". It not only documents the design, it will encapsulate them in stone. Nothing in "models" may reference anything in "controllers", and vice versa.

 (function () {//Anonymous Closure  
 models.Model = jsface.Class(function () {  //add constructor to Pyramid Object

 var t  
   return (BallModel, {  
    constructor: function (controller) {  
      t = this  
      t.scenario = new models.Scenario(t, controller)//use the "model" constructor  
      t.targets = new models.Targets(t, controller)  
      t.elevation = new models.Turret('elevationTurret', 20)  
      t.gunRange = new models.GunRange(t, controller)  
      radio("elevationSpriteEvent").subscribe([t.elevation.setSprite, t.elevation]) //pubsub  
      delete models.Model  
    }  
   });  
 })()  
 }()); //END CLOSURE  
Our Model class instantiates itself and the other member of the Pyramid Object. The last act of the constructor is to delete itself from the "models" object. Since there is an anonymous closure around Model is is now cemented shut. Nothing can reference it at all.


 (function () {//Anonymous Closure  
 models.Scenario = jsface.Class(Sbox, function () {  //add constructor to Pyramid Object
   function isLastScenario(scenarioNum) {  
    if (firstTime)  
      return false  
    else  
      return scenarioNum === t.arr.length  
   }  
   return {//t.theRange, t.targets.arr,  
    constructor: function (modelP, controllerP) {  
      t = this  
      model = modelP  
      controller = controllerP  
      radio("nextTargetEvent").subscribe([nextTarget, this])  
      radio("startScenarioEvent").subscribe([startScenario, this])  
      delete models.Scenario //remove the "model" constructor,   
    }  
 });  
 }()); //END CLOSURE  
All the classes in the "models" object delete themselves from the object.
Now the Pyramid object is empty:

 models = {}  
So nothing can reference anything outside its own class. Which isn't much good, so we use a Publish–subscribe pattern "radio.js" so the occupants of the pyramids can call each other.
The classes here use the jsface.js library, it doesn't matter how you implement classes here.

As shown, you can only have one instance of each class. If you want several instances of one class, leave out the "delete" in the classes constructor and clear the Pyramid object later on:


deleteProperties: function (obj) {
   for (var x in obj)
      if (obj.hasOwnProperty(x))
         delete obj[x];
}
t.deleteProperties(models)
t.deleteProperties(controllers)