JavaScript OOP and MVC - javascript

I'm trying to figure out what MV* framework of many existing can give me what I need...
I am using multipage ASP.NET web application, so I don't want to use routers.
It must be very small...something like Backbone.js, currently I don't want to use something huge like Ember.js or Angular.js.
I will have "modules or controllers" that actually are "single instances" that will get their "data" from server as JSON objects (sometime will be AJAX and sometime embedded in HTML). It's important to be able to use inheritance for modules, so would like to be able to do something like this (pseudo code):
App.Module1 = SomeFramework.create({
model: null,
init:function(data){ this.model = data }
});
App.Module2 = SomeFramework.create(App.Module1, {
config: null,
init: function(data, config){
this._super(data); this.prop = data;
}
});
//Later I will use one of this modules
App.Module1.init(data); /* OR */ App.Module2.init(data, config);
I will have different models that can have many instances.
Modules/Controllers should be able to detect "model changes".
I like Backbone, but it misses some of the things, like creating "single modules" that are able to be inherited and Backbone does not have "controller" because now it's router and it make instances based on URL.

There's nothing smaller than writing plain vanilla javascript, that would be my advice.
And add a couple of micro libraries for DOM manipulation and ajax if you need.
You want to observe your models, but data-binding might be heavy, magic comes at a cost. Why not just use a pub-sub library to communicate to the modules that a model data has changed? It is simple, small and safe.
I'm going to give you some examples with something that I know, the framework soma.js. It is very lightweight, doesn't have a router (I usually advice to use director.js). It provides dependency injection, an event-based observer system, as well as basic OOP such as inheritance. It is very much focused on avoiding highly-coupled code so modules are maintainable and reusable. Vanilla javascript is the key which is possible dependency injection.
Funny, someone thought I was coming from a .NET background with that framework, maybe it appeal to you.
For the ajax part, strip out jquery so there's only the ajax stuff (so it is small), or use something like reqwest.
Here is a quick overview of what you can do.
Inheritance
// create "super class"
var Person = function(name) {
this.name = name;
};
Person.prototype.say = function() {
console.log("I'm a Person, my name is:", this.name);
}
// create "child class" that will inherit from its parent
var Man = function(name) {
Person.call(this, name); // call super constructor
}
Man.prototype.say = function() {
// Person.prototype.say.call(this); // call super say method
console.log("I'm a Man, my name is:", this.name);
}
// apply inheritance
soma.inherit(Person, Man.prototype);
// create Person
var person = new Person("Doe");
person.say();
// create Man
var john = new Man("John Doe");
john.say();
Try it out
Here is another example with some shortcuts.
// create "super class"
var Person = function(name) {
this.name = name;
};
Person.prototype.say = function() {
console.log("I'm a Person, my name is:", this.name);
}
// create an "extend" shortcut
Person.extend = function (obj) {
return soma.inherit(Person, obj);
};
// create "child class" and apply inheritance using an "extend" shortcut
var Man = Person.extend({
constructor: function(name) {
Person.call(this, name); // call super constructor
},
say: function() {
// Person.prototype.say.call(this); // call super say method
console.log("I'm a Man, my name is:", this.name);
}
});
// create Person
var person = new Person("Doe");
person.say();
// create Man
var john = new Man("John Doe");
john.say();
Try it out
Modules
The frameworks makes you able to vanilla javascript so it is very reusable.
Here is what a Model, or Module, or anything else could look like (vanilla javascript):
(function(clock) {
'use strict';
var TimerModel = function() {
};
TimerModel.prototype.update = function() {
// update something
};
TimerModel.prototype.add = function(callback) {
// add something
};
TimerModel.prototype.remove = function(callback) {
// remove something
};
TimerModel.prototype.dispose = function() {
// destroy model
};
clock.TimerModel = TimerModel;
})(window.clock = window.clock || {});
Dependency injection
The framework provides dependency injection, which makes you able to use named variable to get your instances in other modules.
An injection rule could look like that:
injector.mapClass("myModel", Model);
To get your model somewhere else, just use the "named variables", the injector will take care of everything (also very good to solve nested dependencies):
var Module = function(myModel) {
// myModel has been injected
}
Try an example
More information
Communication (pub-sub, Observer Pattern)
A event-based tool (interchangeable with a DOM node for high decoupling) is available to communicate: the dispatcher. You also get it with injection:
var Module = function(myModel, dispatcher) {
// myModel and dispatcher have been injected
}
Dispatch an event:
this.dispatcher.dispatch('do-something');
Listen to an event:
dispatcher.addEventListener('do-something', function(event) {
// react to an event
});
Template
You can use a very powerful plugin as a template engine (real non-destructive DOM manipulation) called soma-template.
Or any other template engine of your choice.
Build an application
Here is an article that make you build an scalable and maintainable application:
http://flippinawesome.org/2013/07/15/soma-js-your-way-out-of-chaotic-javascript/
That's not it, the framework also provide Mediators and Commands to make your code reusable. Check out the site, it has tons of demos.
I hope all this is helping you.
I'm used to write very bare bone application that run fast on mobile, so please ask me precise questions about what you need so I can maybe help.
Romu

Yes, Backbone does not have module driven development or rather Backbone does not follow modular pattern. You can use require.js for Modular pattern. It is a very small library and syncs up well with Backbone.

Related

How to handle inheritance with public and private functions within factory functions in JavaScript?

I am the team lead of a group of ~8 developers. We look after a large website which is split into many 'components' (a component could be a gallery for example - with libraries aside, these 'components' are standalone). We are in the process of splitting things up and part of that task is creating Gulp code to handle the various stages of processing for each of these components (SCSS processing, concatenation, image optimisation etc).
So, I need to come up with a pattern that the team can follow when creating Gulp code for a new 'component'. I need to keep this as simple as possible as many of the developers are new to Gulp. The general idea I want to get to is that we have a base Gulp 'component', which will have all code required to process a standard 'component', but I expect there will be some 'components' that need special gulp code. So, I would like to be able to extend the base Gulp 'component' compilation code in these cases.
In an attempt to learn and to set up a strong foundation for the team have been doing some reading on best approaches to inheritance in JavaScript. I have come across quite a rift in the way people feel about this. What approaches I have considered and what I've gathered:
There are classes in ES6 which I can use in node.js. These classes are shunned by a lot of the big names in the JavaScript world as well as big names from the past (when using classical style languages) for reasons such as it encourages brittle code. Also, you cant do classic style public and private properties/functions, so I struggle to see any real reason why I should go with this.
If I did go this route, I feel I would end up with something like this (code is untested / probably not correct, i'm just dumping my thoughts):
class Component {
constructor(options) {
},
build() {
},
dev() {
}
test() {
},
// Should be private, but wont be
_processStyles() {
},
_processScripts() {
}
}
Factory functions. We're used to using these with the revealing module pattern, and generally I like them. I also believe that Douglas Crockford is a fan of factory functions, so I feel I'm on good ground with this. Now, if I create public and private methods (by returning an object with references only to my public functions) and then I want to extend 'component', in the new factory I would create an instance of 'component' and then extend that. The problem is that I can't override (or even call) the private functions of my 'component' instance, because they are in a different scope that I have no access to. I did read that one way to get around this is to use an object to create a reference to all of the private methods, but then they're not private anymore, so it defeats the object (no pun intended).
var component = function(options) {
var init = function() {
};
var build = function() {
};
var dev = function() {
};
var test = function() {
};
var _processStyles = function() {
};
var _processScripts = function() {
};
return {
init: init,
build: build,
dev: dev,
test: test
};
};
var specialComponent = function(options) {
// Create instance of component
var cmp = component(options);
// Extend it
cmp.extraFunction = function() {
// This will throw an error as this function is not in scope
_processStyles();
}
// Private functions are available if I need them
var _extraPrivateFunction = function() {
}
return cmp;
}
So, I feel like I've missed something somewhere, like I need someone to point me in the right direction. Am I getting too hung up about private functions (feels like it)? Are there better approaches? How would something like this, which seems to lend itself to classical inheritance be best tackled in a DRY (don't repeat yourself) manner?
Thanks in advance,
Alex.

jQuery and object-oriented JavaScript - howto?

I've read this and this (thanks google)
But it doesn't help enough. I'd like to know, if, straight out of the box, without any plugin addons, it's possible to do something like it's possible with prototype, for example:
MyClass = Class.create(Table,
{
cookieName: 'w_myclass',
prefix: 'myclass',
...blabla...
// function
initStr: function()
{
...blabla...
},
// another function
getIndice: function(param)
{
...blabla...
return 0;
}
});
Any idea/suggestions are welcome.
JQuery never had the purpose of being a class framework. It's about page manipulation and tools (like AJAX). You can pound a nail with a fork, but why not use a hammer?
Using native JavaScript to create a class-based inheritance system is asking for trouble unless you're a highly skilled JavaScript programmer. Douglas Crockford will tell you it's possible, but he has a deep understanding if the intricacies of closure etc etc. Also, using native inheritance features becomes unsustainable very quickly if your system grows large.
I highly recommend James Coglan's JS.Class framework. The class definitions will look almost identical to your example. It's not native JS but it works fine with JQuery.
If you want a near object oriented solution using javascript with jquery you can define an object in javascript that will set up your event controllers.
The second half of this post http://www.codescream.com/?p=18 covers that. but i'll write here a resume on how to make an object in javascript that you can use in a near object oriented structure.
It would look something like this:
function myObject(constructorParam1, constructorParam2, anotherOne, blabla){
var text = "";
// this event will be set everyTime you run myObject
$(".foo").click(function(){
text = $(this).text(); // copies the text inside the elements ".foo" to a local variable
doSomething();
});
function aPrivateFunction1(){
}
function aPrivateFunction2(){
}
function internalAdd(a,b){
return a+b;
}
var size = 1; // privateVaribale
var name = blabla;
if(name===undefined){
name="No name";
}
aPrivateFunction1(); // run "aPrivateFunction1()
// you can consider all code above as being part of the constructor.
// The variables declared above are private, and the functions are private as well
// bellow are public functions that you can access in an OOP manner
return {
getSize: function(){
return size;
},
setSize: function(newSize){
size = newSize;
},
getName: function(){
return name;
},
setName: function(newName){
name = newname;
},
addAndTurnPositive: function(n1,n2){
var val = internalAdd(n1,n2);
if(val<0){
return val*-1;
}
return val;
}
}
}
// then you can run it like
var anInstance = myObject("aaa",1234,"asdak",123);
anInstance.setSize(1234);
var t = anInstance.addAndTurnPositive(-5,2);
In a word, no. jQuery doesn't offer any class and inheritance functionality. You'd need to include another library, such as klass (although there is a jQuery plugin which ties it in more closely with jQuery)

Advantages & Disadvantages of Dependency-Injecting Non-Instantiable Objects

What, in your opinion, are the advantages and disadvantages of dependency-injecting non-instantiable objects in JavaScript?
Some context you may want to explore are:
Unit-testing
Is it worth dep-injecting it? After all, you can overwrite the non-instantiable "static" dependency to a fake object for each test even without dep-injection.
Refactoring
Will it become more difficult to locate & refactor the non-instantiable dependency?
Readability
Which implementation is easier to follow? Is the implicitness or explicitness important to you?
File-size
Code
Non-instantiable object:
WindowFactory = {
buildWindow: function() {
return {};
}
};
Dependency-Injected:
(House = function(windowFactory) {
this.windowFactory = windowFactory;
}).prototype = {
build: function() {
var window = this.windowFactory.buildWindow();
}
};
var house = new House(WindowFactory);
vs. The Non-Dependency-Injected variant:
(House = function() {
}).prototype = {
build: function() {
var window = WindowFactory.buildWindow();
}
};
var house = new House();
Context
My primary goal is to make the code above testable. I've gotten into a
habit of externalizing instantiable dependencies (e.g var window = new
Window(); var house = new House(window);). This helps when unit-
testing instantiable objects (e.g. House), since instead of the real
dependencies (Window) I can instantiate the object with a fake (var
fakeWindow = {}; var house = new House(fakeWindow);), and not have to
worry about redundantly testing the dependencies while testing my
object. (This form of dependency-injection is also useful when testing
objects that depend on some data being retrieved via XHR, DOM-events,
sessionStorage, or cookie.)
Now, when the dependency is an instantiable object itself, the
benefits are clear to me; but when the dependency is a non-
instantiable object (e.g. WindowFactory in the code above), I have
second thoughts about the usefulness.
If you get some gain in unit-testing, that might be more than enough for me. You'll be able to cleanly test the functionality without depending on global/external state. The added bonus then becomes the readability; you clearly show which global state/api you depend on in the arguments of your function.
Being able to change the static methods in the setup/teardown of the tests is a workaround for the problem, but I personally find it to be error-prone and a chore doing it.

Howto move from object based language to server side Node.js Javascript for big projects?

I've decided to get used to using Javascript as my server sided (I'm using Node.js) language to setup a webserver, create server deamons and a lot more. This is a rather big project, which means that I have to get used to the language and get myself an optimal setup before actually starting to avoid overhead and unneeded hassle.
I have been looking for sources that'd explain the basics of functional programming in big projects. Unfortunately, most sources talk only about basic Javascript meant for simple tricks in a browser.
Two helpful links that explained how object creation works in Javascript were http://howtonode.org/object-graphs and http://howtonode.org/object-graphs-2.
In the end, it seems most wise to create an object like:
function MyObject(constructorMemberOne, constructorMemberTwo) {
this.constructorMemberOne = constructorMemberOne;
this.constructorMemberTwo = constructorMembertwo;
this.doSomething = function doSomething() {
//
}
}
Now, I'm looking for a complete Javascript language reference. So far, https://developer.mozilla.org/en/JavaScript/Reference seems to be most complete.
Q1: is this the recommended ECMAScript language reference? I'm asking mostly because it's sourced by a company that's mostly working in the browser industry, yet Javascript is not just there for browsers -- maybe there are sources that I'm unaware of.
Secondly, I'm used to creating a new file for every class I create where the file name represents the name of the class. Q2: Is this recommended practice in Javascript (V8, Node.js) too? How would one "import" this class?
This "importing" leads me to my confusingness about Node.js's "require". I know it's not the same. Require basically loads another file which then has it's own namespace, meaning that it's variables are out of the scope of the file that's requireing this file. For my classes however, I want to have methods that are available to the class that is "importing" (quotes as I am not sure whether this is even possible) this class. Eg.:
var utils = require("utils/MainUtils.js");
utils.doSomething();
As far as I know, this doSomething() method is only available if it was set like:
function MainUtils() {
exports.doSomething = function doSomething() {
//
}
}
Q3: Is that correct? Doesn't that seem quite abnormal?
Q4: Are there any other blogs or resources that are helpful in getting my setup working, like howtonode.org?
Finally, Q5: have there been any efforts into making all this inheritance, object creation, project structure, namespacing etc. easier for big projects? Any libraries or something for this purpose?
Hopefully my questions are clear. Any help is appreciated. Thanks.
is this the recommended ECMAScript language reference?
Well the official ECMAScript language reference is the ECMA-262 itself. But unfortunately this is completely unreadable even by the standards of standards documents.
ECMA do not produce any materials aimed at end-programmers and there's no one tutorial considered “best”. The MDC link looks decent, at least. (Most JavaScript tutorials are absolutely horrible and full of errors. Which is partly JavaScript's fault for having so many... quirky... features, but still.)
In the end, it seems most wise to create an object like:
There is unfortunately no widely-accepted-‘best’ way to implement a class/instance system in JavaScript. A lot of frameworks have their own systems, or you can brew your own. Your example code creates a new instance of each method for each object instance, which you might consider suboptimal compared to JS's native prototyping. (Normally this approach is used with a var that= this in the closure to avoid this-binding problems in callback code.) You would also need to exercise care in how you create subclasses and initialise them in the constructors.
See this question for a discussion on approaches to class/instance in JS.
I'm used to creating a new file for every class I create
Yeah, that's a Java wart you shouldn't bring to JS.
Keep your source files in manageable chunks of related classes and functions. Sometimes that will be one public class per file, more often it won't be.
How would one "import" this class?
JS itself has no native import functionality. In browsers you do it by inserting <script> tags or eval​ing code fetched by XMLHttpRequest, and have to take care of keeping variables in separate namespaces manually. In Node.js and other places where you're working with CommonJS, you use modules and require().
Is that correct?
Yes.
Doesn't that seem quite abnormal?
I don't think so. It's similar to other scripting languages, where it proves very useful. It's only really Java that forces you to wrap up a compilation unit into a single class.
I came up with the following after reading a book called Pro Javascript Design Patterns. However, I've been told that it's not good to think like this (private, public, static, etc.) in Javascript:
var SomeClass = (function() {
this.prototype.publicStaticMember = "this is a public static variable",
this.prototype.publicStaticMethod = function() {
return "this is a public method: cannot access private members/methods, but can access privileged and public members/methods";
}
var privateStaticMember = "this is a private static variable";
function privateStaticMethod() {
return "this is a private static method: can only access private members/methods";
}
//instance part
return function() {
this.publicInstanceMember = "this is a public instance variable";
var privateInstanceMember = "this is a private instance variable";
this.publicInstanceMethod = function() {
return "this is a privileged method: can access both public and private members/methods";
}
var privateInstanceMethod = function() {
return "this is a private method: can access both public and private members/methods but is private";
}
}
})();
It'd be instantiated like this:
var someInstance = new SomeClass().("param1", "param2");
Any comments? Should I read an other book?
If you haven't already, checkout the videos by Douglas Crockford. He has a bunch of videos that talk about the prototypal aspects of JavaScript.
Google for 'Douglas Crockford Java Programming Language Video'. Here is a link to the first part in the series: http://video.yahoo.com/watch/111593/1710507
The defineClass npm package provides simple yet powerful OOP for JavaScript with support for traits (mixins) and nested classes. Here is an example of usage:
var defineClass = require("defineClass").defineClass;
var Person = defineClass({
cash: 0,
constructor: function (firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
},
greet: function (name) {
console.log("Hello " + name + ". My name is " + this.firstName);
},
earn: function (amount) {
this.cash += amount;
}
});
var Developer = defineClass({
_super: Person,
// override a field default value
cash: 100,
// override the constructor
constructor: function (firstName, lastName, language) {
// you may have code before the base constructor call
// call the base constructor
this._super(firstName, lastName);
this.language = language;
}
// override a method
greet: function (name) {
console.log("Hey, " + name + ". I'm " + this.firstName)
},
// override a method and call its base method
earn: function (amount) {
return this._super(amount * 1.2);
}
});
Read more in the readme: https://github.com/nodirt/defineClass
Installation:
$ npm install defineClass

What is the right way to wire together 2 javascript objects?

I'm currently facing a conundrum: What is the right way to wire together 2 javascript objects?
Imagine an application like a text editor with several different files. I have some HTML page that represents the view for the notebook. I have a file notebook.js that contains class definitions for NotebookController and Notebook View.
NotebookControler object responsible for performing business logic on the Notebook like "Save Notebook," "Load Notebook," "New Notebook." NotebookView is responsible for managing the HTML that is used for presentation. It does low level stuff like "get/set notebook body" "get/set notebook name." It also listens for DOM events (onClick) and fires business events (saveNotebook). This is my attempt at the Passive View pattern.
I want my javascript client-side code to be object-oriented, separated concerns, and unit-testable. I want to test NotebookController with a mock NotebookView and vice versa. This means that I can't just instantiate a NotebookView inside the NotebookController. So do I
Put some logic in my notebook.js that wires the 2 together
Have a global function in my application that knows to instantiate one of each and wire them together
Use Dependency Injection, either a home-grown one or something like SquirrelIoc
In Java, the choice is a natural one: use Spring. But that doesn't seem very JavaScript-y. What's the right thing to do?
Dependency injection is probably your best bet. Compared to Java, some aspects of this are easier to do in JS code, since you can pass an object full of callbacks into your NotebookController. Other aspects are harder, because you don't have the static code analysis to formalize the interface between them.
Thanks for the insight. I ended up writing a simple JavaScript dependency injection utility. After debating for a while and your comments, it occured to me that DI was really the right answer because:
It totally separated the concerns of wiring from the business logic while keeping the wiring logic close to the things being wired.
It allowed me to generically provide a "you're all wired up" callback on my objects so that I could do a 3 phase initialization: instantiate everything, wire it all up, call everyone's callbacks and tell them they're wired.
It was easy to check for dependency missing problems.
So here's the DI utility:
var Dependency = function(_name, _instance, _dependencyMap) {
this.name = _name;
this.instance = _instance;
this.dependencyMap = _dependencyMap;
}
Dependency.prototype.toString = function() {
return this.name;
}
CONCORD.dependencyinjection = {};
CONCORD.dependencyinjection.Context = function() {
this.registry = {};
}
CONCORD.dependencyinjection.Context.prototype = {
register : function(name, instance, dependencyMap) {
this.registry[name] = new Dependency(name, instance, dependencyMap);
},
get : function(name) {
var dependency = this.registry[name];
return dependency != null ? dependency.instance : null;
},
init : function() {
YAHOO.log("Initializing Dependency Injection","info","CONCORD.dependencyinjection.Context");
var registryKey;
var dependencyKey;
var dependency;
var afterDependenciesSet = [];
for (registryKey in this.registry) {
dependency = this.registry[registryKey];
YAHOO.log("Initializing " + dependency.name,"debug","CONCORD.dependencyinjection.Context");
for(dependencyKey in dependency.dependencyMap) {
var name = dependency.dependencyMap[dependencyKey];
var instance = this.get(name);
if(instance == null) {
throw "Unsatisfied Dependency: "+dependency+"."+dependencyKey+" could not find instance for "+name;
}
dependency.instance[dependencyKey] = instance;
}
if(typeof dependency.instance['afterDependenciesSet'] != 'undefined') {
afterDependenciesSet.push(dependency);
}
}
var i;
for(i = 0; i < afterDependenciesSet.length; i++) {
afterDependenciesSet[i].instance.afterDependenciesSet();
}
}
}
I would say, just wire them together:
function wireTogether() {
var v = new View();
var c = new Controller();
c.setView(v);
}
But then of course another question raises - how do you test the wireTogether() function?
Luckily, JavaScript is a really dynamic language, so you can just assign new values to View and Controller:
var ok = false;
View.prototype.isOurMock = true;
Controller.prototype.setView = function(v) {
ok = v.isOurMock;
}
wireTogether();
alert( ok ? "Test passed" : "Test failed" );
There is also a framework for dependency injection for JavaScript: https://github.com/briancavalier/wire
I have a inversion of control library for javascript, I'm pretty happy with it. https://github.com/fschwiet/jsfioc. It also supports events, so if you want to have a startup event thats fine. It could use more documentation...
http://github.com/fschwiet/jsfioc
Another (newer?) option, which has better documentation and support, is requireJS (http://requirejs.org/).
I'll try to take a stab at this, but it will be a little difficult without seeing any actual code. Personally, I've never seen anybody do such a specific attempt at (M)VC with JavaScript or IoC for that matter.
First of all, what are you going to test with? If you haven't already, check out the YUI Test video which has some good info on unit testing with javascript.
Secondly, when you say "the best way to wire up that aggregation" I would probably just do it as a setter w/the controller
// Production
var cont = new NotebookController();
cont.setView( new NotebookView() );
// Testing the View
var cont = new NotebookController();
cont.setView( new MockNotebookView() );
// Testing the Controller
var cont = new MockNotebookController();
cont.setView( new NotebookView() );
// Testing both
var cont = new MockNotebookController();
cont.setView( new MockNotebookView() );
But this makes some big assumption on how you've designed your controller and view objects already.

Categories

Resources