Architecture for creating a JavaScript framework - javascript

Around one year ago we started a web system that over the time has grown quite a bit. From the beginning the goal was to build reusable code that would speed up the development of future projects, and it has. With every new project, the reusable code from the previous was taken and build upon it.
At the moment, the server side code is really clean, and there is a clear separation between the "framework" (generic functionality) and the project specific logic.
However, the javascript has grown out of control. For the page specific javascript (button events, ajax calls, etc.) we've been using closures and the module pattern. But the javascript common files (the ones we import in every page), are full of functions with no association between them beyond some similarities on the names.
Because of this I'm now trying to build a sort of framework (easily reusable and maintainable code) encapsulating the logic and functions we already have. It should be one "core" object and several optional "extensions". They would be in separate files to improve the order of the code. Specifically, I'm trying to achieve the following:
Encapsulation of the code to prevent name collisions. We are very comfortable with the private/public separation of the closures.
Extendable functionality, something like the open/close principle. The tricky part here is that an extension might want to access a private method of the core.
I've been reading a lot on OO in javascript, and I've even tried to understand how jQuery does it, but I'm still unable to get my head around it. For the architectural side, it seems that I should be building a module or service framework, but the ones I've found are much more complex than what I want to achieve.
If it weren't for the tricky part mentioned earlier, a simple $.extension() would do, but I'm stuck in the how to access a core private method from an extension part. In short, my question would be: Is there a recommended architecture in javascript to build something like the following example?
var framework = function () {
//Private variable
var internalState = 1;
//Private method
var validState = function () { ... }
//Public methods
return {
commonTask1: function () { ... },
commonTask2: function () { ... }
}
}();
framework.addMoreFunctionality(function () {
var specificData = '';
return {
extensionMethod: function () {
//TRICKY PART HERE
if (core.validState()) { ... }
}
}
}());

Just return a function from the framework module.
return {
isValidState: function() { ... }
commonTask1: function () { ... },
commonTask2: function () { ... }
}
The isValidState function could then check the internal state.
// isValidState
function() {
if (validState()) {
return true;
}
return false;
}
Check if the state is valid then by calling core.isValidState(); Like this you will not get any reference to any "private" variable inside the framework core because the functions returns a bool and not a direct reference to any objects.

Have you explored DOJO ? It has module system, a build system and very elaborate OO framework implemented.
You can have your own modules / "base Dijits" that will help you implement "generic modules/widgets" and then extend them per-project, by writing / adding specific capabilities the way you have described.
DOJO is not exactly in Vogue, but if your application deals with forms like interface, then it's definitely a candidate.

Related

Cleaning up a large piece of Javascript code

I am writing an application in Titanium for Android. I have a lot of code in a single JS file. I would like to know if there is any function like php's include to break the code into multiple files and then just include them.
Thanks
Use the CommonJS / RequireJS approach, specifically the require command. This is the (strongly) recommended way for dealing with large systems in Titanium, and is well documented on their website, along with many best practices for dealing with JavaScript modularization specific to Titanium. Here is the documentation from Titanium on this.
For example, to create a module that encapsulates a 'view' of some kind, put it in a file named MyCustomView.js with this content:
// MyCustomView.js
function MyCustomView(message) {
var self = Ti.UI.createView({
backgroundColor : 'red'
});
var label = Ti.UI.createLabel({
text : message,
top : 15,
.... // Other initialization
});
// ... Other initialization for your custom view, event listeners etc.
return self;
}
module.exports = MyCustomView;
Now you can easily use this module in another class, lets assume you put this in your /Resources folder, lets load the module inside app.js and add it to the main window.
// app.js
var MyCustomView = require('MyCustomView');
var myView = new MyCustomView('A message!');
Titanium.UI.currentWindow.add(myView);
You can use this approach to make custom views, libraries of reusable code, and anything else you would like. Another common thing would be to have a Utility class that has many different helper functions:
// Utility.js
exports.cleanString = function(string) {
// Replace evil characters
var ret = string.replace(/[|&;$%#"<>()+,]/g, "");
// replace double single quotes
return ret.replace(/"/g, "''");
}
This method can be easily used like this:
// app.js
var Utility = require('Utility.js');
Ti.API.info(Utility.cleanString('He##o W&orld$'));
Another common method I use it for is to implement the Singleton pattern as each module loaded is its own functional context, so if you like, you can have values that persist:
// ManagerSingleton.js
var SpriteManager = {
count : 0
};
exports.addSprite = function() {
SpriteManager.count++;
}
exports.removeSprite = function() {
SpriteManager.count--;
}
You would load and use this much the same way as Utility:
// app.js
var ManagerSingleton = require('ManagerSingleton');
ManagerSingleton.addSprite();
This is something of a more elegant solution instead of using global variables. These methods are by no means perfect, but they have saved me a lot of time and frustration, and added depth, elegance, and readability to my Titanium code for Apps of all sizes and types.
There are two dominant module systems in the Javascript world.
One is the CommonJS and the second is AMD. There is a lot of discussion about which one is best and for what purpose. CommonJS is more widely used for server side JS while AMD is used mostly for browser JS.
RequireJS (requirejs.org) seems to be the most popular AMD system.
For information on JS module systems please read here: http://addyosmani.com/writing-modular-js/

Use of prototype for single instance functions in JavaScript

For performance optimization I'm using a single JavaScript file to handle all the pages of the website I'm working on.
The basic structure I'm using is as followed:
(function($) {
// Shared functions ...
// A function for every page
function Page1() {
}
Page1.prototype = {
init: function() {
//...
},
//more functions
};
// more pages
$(document).ready(function() {
if ($('#page1uniqueidentifier').length) {
var page1 = new Page1();
page1.init();
}
// more pages
}
}) (jQuery);
I'm not an experienced JavaScript programmer so I've been searching a lot about best practices and different ways of structuring my code and I've ended up choosing this one but I'm not really sure about it and I have a few questions:
Is it worth it to use prototype if I'm never gonna have more than a single instance of a page? I think I understand how prototype works and that I'm not gaining any performance there. But I'm using it just as a best practice because in the case different instances would exist, these functions would be the same in every instance.
Is there a better way to structure the code?
Should I put the call of the init function inside the constructor and then only call new Page1()?
function Page1() {
this.init();
}
if ($('#page1uniqueidentifier').length) {
new Page1();
}
For performance optimization I'm using a single JavaScript file to
handle all the pages of the website I'm working on
That makes no sense. You should separate code into files, and then run all your js files thru a minimizer/concatenator to package it up.
Anyway, to answer your questions,
if you are only going to have 1, then prototype won't buy you anything. However, if you are going to use more than 1, would you go back and change it? Plus, using prototype wont hurt you either, so you might as well do it for learning.
You should create the files that make sense according to the functionality implemented. I would separate your object definition into its own file, for example, so when you look at that file, all you see is the code for that object.
If you have a constructor function, you don't really need init, do you?

Gloal Abatement - Using a Single Object Literal

So I just need a sanity check on the way in which I layout my code for an application. I'm always keen to learn better approaches.
I basically use an Object Literal to organise my code meaning that I have one single global variable. Then for each section of the application I create a separate object - something like:
var MYAPP = {
init : function() {
//site wide common js
},
sections : {
homepage : function() {
//homepage js
},
anotherpage : function() {
//another page js
tools.usefultool();
}
},
tools : {
usefultool : function() {
//useful reuseable method
}
}
};
My question is while this helps code organisation, I'm wondering about objects being initialised but never used. For example - if I'm on a site's homepage I'll just call MYAPP.sections.homepage() . I don't actually need any of the other objects so I'm wondering - does this structure have a performance implication? Is there a better way? The structure closely follows the the great Rebecca Murphy article "Using Object to Organise Your Code" (http://blog.rebeccamurphey.com/2009/10/15/using-objects-to-organize-your-code).
Thanks!
Yes, there's always a performance hit in unused code as the parser has to actually interpret the code even if it's not executed. But any performance hit here is so minute that you're never going to notice it. The only real hit in unused code like this is in the bandwidth required to download it. If you have a 100kb file downloaded that you never use then you're wasting the time to download that file.

Dependency inversion principle in JavaScript

Is anyone able to help illustrate Dependency inversion principle in JavaScript jQuery?
Which would highlight and explain these 2 points:
A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.
What are abstractions or high/low level modules?
This will really help in my understanding, thanks!
I would say the DIP applies in JavaScript much the same way as it applies in most programming languages, but you have to be aware of the role of duck typing. Let's do an example to see what I mean...
Let's say I want to contact the server for some data. Without applying DIP, this might look like:
$.get("/address/to/data", function (data) {
$("#thingy1").text(data.property1);
$("#thingy2").text(data.property2);
});
With DIP, I might instead write code like
fillFromServer("/address/to/data", thingyView);
where the abstraction fillFromServer can for the particular case where we want to use jQuery's Ajax be implemented as
function fillFromServer(url, view) {
$.get(url, function (data) {
view.setValues(data);
});
}
and the abstraction view can be implemented for the particular case of a view based on elements with IDs thingy1 and thingy2 as
var thingyView = {
setValues: function (data) {
$("#thingy1").text(data.property1);
$("#thingy2").text(data.property2);
}
};
Principle A:
fillFromServer belongs in a low-level module, handling as it does the low-level interaction between the server and the view. Something like, say, a settingsUpdater object would be part of a higher-level module, and it would rely on the fillFromServer abstraction---not on the details of it, which are in this case implemented via jQuery.
Similarly, fillFromServer does not depend on specifics of the DOM elements and their IDs to perform its work; instead, it depends on the abstraction of a view, which for its purposes is any type that has a setValues method. (This is what is meant by "duck typing.")
Principle B:
This is a bit less easy to see in JavaScript, with its duck-typing; in particular, something like view does not derive from (i.e. depend on) some kind of viewInterface type. But we can say that our particular instance, the thingyView, is a detail that "depends" on the abstraction view.
Realistically, it is "depending" on the fact that callers understand what kind of methods should be called, i.e. that callers are aware of the appropriate abstraction. In the usual object-oriented languages, it is easier to see the dependency of thingyView explicitly on the abstraction itself. In such languages, the abstraction would be embodied in an interface (say, IView in C# or Viewable in Java), and the explicit dependency is via inheritance (class ThingyView : IView or class ThingyView implements Viewable). The same sentiment applies, however.
Why is this cool? Well, let's say one day I needed to put the server data into textboxes with IDs text1 and text2 instead of <span />s with IDs thingy1 and thingy2. Furthermore, let's say that this code was being called very very often, and benchmarking revealed that critical performance was being lost via the use of jQuery. I could then just create a new "implementation" of the view abstraction, like so:
var textViewNoJQuery = {
setValues: function (data) {
document.getElementById("text1").value = data.property1;
document.getElementById("text2").value = data.property2;
}
};
Then I inject this particular instance of the view abstraction into my fillFromServer abstraction:
fillFromServer("/address/to/data", textViewNoJQuery);
This required no changes to fillFromServer code, because it depended only on the abstraction of a view with a setValues method, and not on the details of the DOM and how we access it. Not only is this satisfying in that we can reuse code, it also indicates that we have cleanly separated our concerns and created very future-proof code.
EDIT:
This shows the usage of DIP in raw JavaScript and a less-complete jQuery example. However, the following description can be easily applied to jQuery. See jQuery example at the bottom.
The best way is to take advantage of the "Adapter Pattern" -- also called a "wrapper".
An Adapter is basically a way of wrapping an object or module in such a way that it provides the same consistent interface to its dependents. That way, the dependent class (usually a higher-level class) can easily swap out modules of the same type.
An example of this would be a high-level (or supra) module whom depends on Geo/Mapping modules.
Lets analyze this. If our supra module is already using GoogleMaps but then management decides its cheaper to go with LeafletMaps -- we don't want to have to rewrite every method call from gMap.showMap(user, latLong) to leaflet.render(apiSecret,latLong, user), et al. This would be a nightmare to have to port our application from one framework to an other this way.
What we want: We would like a "wrapper" that provides the same consistant interface to the supra module -- and do this for every lower-level module (or infra module).
Here is a vary simple example:
var infra1 = (function(){
function alertMessage(message){
alert(message);
}
return {
notify: alertMessage
};
})();
var infra2 = (function(){
function logMessage(message){
console.log(message);
}
return {
notify: logMessage
};
})();
var Supra = function(writer){
var notifier = writer;
function writeMessage(msg){
notifier.notify(msg);
}
this.writeNotification = writeMessage;
};
var supra;
supra = new Supra(infra1);
supra.writeNotification('This is a message');
supra = new Supra(infra2);
supra.writeNotification('This is a message');
Notice that no matter which type of lower-level module "write" we use (in this case infra1 and infra2), we do not have to rewrite any of the implementation of our high-level module, Supra. This is because DIP takes advantage of two different Software Design Principles: "IoC" (Inversion of Control) and "DI" (Dependency Injection).
The best analogy that I've come across is the picture shown below.
Every electrical source relies on an interface specific for the types of things that need to plug into it.
jQuery Description:
This pattern can be easily applied to the usage of frameworks such as jQuery. One example would be the simple DOM-Query handle. We can use DIP to allow loose-coupling so that if we ever decide to switch frameworks or rely on native DOM-Query methods, maintenance is easy:
var jQ = (function($){
return {
getElement: $
};
})(jQuery);
var nativeModule = (function(){
return {
getElement: document.querySelector
};
})();
var SupraDOMQuery = function(api){
var helper = api, thus = this;
function queryDOM(selector){
el = helper.getElement(selector);
return thus;
}
this.get = queryDOM;
};
var DOM;
DOM = new SupraDOMQuery(jQ);
DOM.get('#id.class');
DOM = new SupraDOMQuery(nativeModule);
DOM.get('#id.class');
Obviously, this example would need magnitudes of more functionality in order to be practical, but I hope it gets the point across.
Basically, the differences between an Adapter and a Facade become somewhat trivial. In a Facade, you're looking at probably a single module that wraps an API or another module; whereas an Adapter creates a consistent Facade API for each of its modules, and exploits this technique to obviate tight-coupling.
Most of the JavaScript Design Patterns books go over the Adapter Pattern; one that specifically goes over a 'jQuery Adapter' is Learning JavaScript Design Patterns by Addy Osmani published by O'Reilly -- here. However, I also advise looking into Pro JavaScript Design Patterns by Dustin Diaz and Ross Harmes published by Apress -- check it out. Nevertheless, I think its important to understand the context in which we plan to implement DIP in relation to jQuery.
I hope this helps to clarify things :)
Here's my understanding and would appreciate feedback. The key test is 'who has the power'.
In a traditional implementation
High Level (HL) Code --> Low Level (LL) Code.
So for example
LL code
function LLdoAlert(text) { alert(message); }
function LLdoConsole(text) { console.log(message); }
HL Code
LLdoAlert('Hi there');
LLdoConsole('Hi there');
Here the LL code has the power. Change the LL function name for example, HL code breaks.
With dependency inversion
High Level (HL) Code --> HL/LL service interface <-- Low Level (LL) Code.
Where the HL code also owns the service interface. So for example
HL Code
var HLdoOutputSI = {
exec: function(method, text) {
if (this[method]) this[method](text);
},
register: function(name, fn) {
this[name] = fn;
}
}
HLdoOutputSI.exec('alert', 'Hi there');
HLdoOutputSI.exec('console', 'Hi there');
LL code:
HLdoOutputSI.register('alert', function(text) { alert(message); });
HLdoOutputSI.register('console', function(text) { console.log(message); }
Here we can now have any number of LL code items registering functions, but none break the HL code. (If none register, functionality is skipped). If LL code want's to play, they have to follow the HL code method. I.e. power now shifted from LL to HL.
Dependency inversion principle in JavaScript jQuery
There's no any connection between DI and jQuery. DI is all about the structure and assembling application from compoents. jQuery is a handy wrapper around DOM, nothing more, it has no any structure or components.
You can use DI to assembly Your JavaScript Application, but it would looks much the same no matter do You use jQuery or not.

JavaScript structure, right way?

Iam trying to get better in javascript coding. Away from 1000 lines of code in one file. But iam not sure if this is the "right" way:
RequireJS to load files when needed inside "boot.js":
require([
"library/jquery.form/jquery.form",
"app/eventManager",
"app/myapp"
], function() {
$(function() {
MyApp.init();
});
});
MyApp.js
var MyApp = {
init: function() {
MyApp.mainController();
},
// this is our controller, only load stuff needed..
mainController: function() {
//controller = set from php/zendframework
switch (controller) {
case 'admin':
MyApp.initAdmin();
break;
default:
break;
}
},
// action for admin controller
initAdmin: function() {
//lazy load
require(["app/admin/admin"], function(){
MyApp.admin.init();
});
}};
MyApp.admin.js
MyApp.admin = {
init : function() {
if (permisson != 'admin') {
console.log('Permission denied.');
return false;
}
MyApp.admin.dashboard.init();
}
};
MyApp.admin.dashboard = {
init: function() {
MyApp.admin.dashboard.connectEventHandlers();
MyApp.admin.dashboard.connectEvents();
MyApp.admin.dashboard.getUserList('#admin-user-list');
},
connectEvents: function () {
EventManager.subscribe("doClearCache", function() {
MyApp.admin.dashboard.doClearCache(url);
});
EventManager.subscribe("doDeleteUser", function() {
MyApp.admin.dashboard.doDeleteUser(url);
});
},
What other "styles" are common? or this a goodway to structure code? THere a lot of examples in the net, but i was not able to find "real life" code..
And one of biggest "problems" when does i need ".prototype" ?
JavaScript Patterns is a good reference for various ways of structuring code.
It would also be a good idea to study the source code of libraries such as jQuery.
One change I would make to your code is to avoid repeating 'event' strings everywhere.
You could reduce this by doing something like:
var app = {
events : {
someEvent : "someEvent"
}
}
EventManager.subscribe(app.events.someEvent, someFn);
EventManager.publish(app.events.someEvent);
I would also avoid calling console.log directly and use a wrapper such as this which provides a fallback if not console is available
N.B Angus Croll has a decent blog where he mentions js structure/namespacing etc
and there is some really good knowledge being shared over at JsMentors from well versed js ninjas
I defer to Douglass Crockford on all matters pertaining to JavaScript best practices.
Here is his homepage: http://javascript.crockford.com/.
Here is a great book on what to do and what not to do in JavaScript. http://www.amazon.com/exec/obidos/ASIN/0596517742/wrrrldwideweb
Here is his amazing tool which can automatically tell you if you are employing any worst practices. http://www.jslint.com/
As to the prototype question, you use prototype when you want to employ prototypal inheritance, or create a "static" class function which will be present for all instances of that class without consuming memory for each instance.
Require.js is great tool, you can use it also on the client side. But be careful when you use it on mobile. In such case you should either use the editor to navigate better in one file or use thing like sprocket. It is a "precompiler", does not put any additional library to your code.
I passed through your sliced up code. Probably you should define the different parts as modules, read the requirejs documentation for defining modules, it gives good assistance.
But think twice whether you really need for organizing your code an extra library.
In case you are building something more complex, for example with multiple product modules and sub modules, I recommend creating a context hierachy for your modules. Also make the UI components to be self-contained so that you have templates, css, logic, assets, localization etc for a particular UI component in a single place.
If you need to refer a reference architecture for large scale js development see http://boilerplatejs.org. I'm the main author of it and it demonstrates a lot of patterns that are useful in complex product development.

Categories