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.
- Organises your classes into privately scoped groups "Pyramids"
- Nothing outside a Pyramid may access anything inside the Pyramid, the Pyramids are loosely coupled.
- Each Pyramid publishes selected methods so that other Pyramids may subscribe to them.
- 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},
controllers = {Clicks: null, Controller: null, Events: null},
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
(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
Now the Pyramid object is empty:
models = {}
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)