Create MVC Framework (Architect the Structure) Part 2

javascript_mvc_architecture

In this article we're going to learn about design patterns and Architeting the framework

Design patterns

First of all what is a pattern ? and Why ?

A pattern is a reusable solution that can be applied to commonly occurring problems in software design - in our case - in writing JavaScript web applications. Another way of looking at patterns are as templates for how we solve problems - ones which can be used in quite a few different situations.

Why ?

Patterns are proven solutions: They provide solid approaches to solving issues in software development using proven techniques that reflect the experience and insights the developers that helped define them bring to the pattern.
Patterns can be easily reused: A pattern usually reflects an out of the box solution that can be adapted to suit our own needs. This feature makes them quite robust.
Patterns can be expressive: When we look at a pattern there’s generally a set structure and vocabulary to the solution presented that can help express rather large solutions quite elegantly.

Categories of design patterns

  1. Creational Design Patterns
  2. Structural Design Patterns
  3. Behavioral Design Patterns

Do you know about "class" in Javascript ?

Keep in mind that there will be patterns in this table that reference the concept of "classes". JavaScript is a class-less language, however classes can be simulated using functions.

// A car "class"
function Car( model ) {
    this.model = model;
    this.color = "silver";
    this.year = "2012";
 
    this.getInfo = function () {
        return this.model + " " + this.year;
    };
}
var myCar = new Car("ford");
myCar.year = "2010";
console.log( myCar.getInfo() );

Patterns

  • Constructor Pattern
  • Module Pattern
  • Revealing Module Pattern
  • Singleton Pattern
  • Observer Pattern
  • Mediator Pattern
  • Prototype Pattern
  • Command Pattern
  • Facade Pattern
  • Factory Pattern
  • Mixin Pattern
  • Decorator Pattern
  • Flyweight Pattern

In this section i'm not going to explain all of those. Please refer this to get more understanding on design patterns.

About module pattern

The Module pattern was originally defined as a way to provide both private and public encapsulation for classes in conventional software engineering.

In JavaScript, the Module pattern is used to further emulate the concept of classes in such a way that we're able to include both public/private methods and variables inside a single object, thus shielding particular parts from the global scope. What this results in is a reduction in the likelihood of our function names conflicting with other functions defined in additional scripts on the page.

Privacy

The Module pattern encapsulates "privacy", state and organization using closures. It provides a way of wrapping a mix of public and private methods and variables, protecting pieces from leaking into the global scope and accidentally colliding with another developer's interface. With this pattern, only a public API is returned, keeping everything else within the closure private.

Example:

var testModule = (function () {
     var counter = 0;
     return {
          incrementCounter: function () {
          return counter++;
    },
    resetCounter: function () {
          console.log( "counter value prior to reset: " + counter );
          counter = 0;
   }
 };
 
})();
 
// Usage:
 
// Increment our counter
testModule.incrementCounter();
 
// Check the counter value and reset
// Outputs: counter value prior to reset: 1
testModule.resetCounter();

Architecting the framework

In the above picture we can observe the flow. We've constants, factory, routes and cotrollers.

Let's create some rules.

  1. You should write your code which is repeatable in "Factory" and if a factory is dependant on other factory then you should be able to import it into your factory.
  2. These factories should be instantiated when the project gets loaded.
  3. Constants should be able to modified in any component like controller or factory.
  4. We should be able to define routes that means when particular route comes then the specified controller should get executed.
  5. The controllers are the functions which should be able to import factories and constants which are mapped for urls.
  6. These controller should get executed when the particular url comes.

Let's prepare some Syntactical structure

Creating App

var app = MiApp();

If we've a structure like this then we can create multiple apps.

Creating factory

app.factory('factory name', ['dependancy1', 'dependacy2', function(dependacy1, dependancy2){
 //you should access dependancy1
    return {
    'publicAccess': function(){
         return "something"
     }
    }
}]);

Creating constants

app.constants('constant name', function(){
 return {
 'item1':'val1',
 'item2':'val2'
 }
});

Wait,

You don't find any difference between factory and constants ?

I'll explain later.

Creating routes

app.routes('routeurlwithregularexpression','contrllername');

example:

app.routes('test/:id/', 'TestController');

Creating Controllers

app.Controller('TestContrller', ['dependancy1', 'dependancyn', function(dependancy1, dependancyn){
 //your stuff that runs when the page gets loaded
 
}]);

This assumed MVC structure needs to get developed and then needs to get implemented.

So let's develop the structure.

Observe the public items and Private items

If MiApp is a module then the public items should be

  1. Factory
  2. Routes
  3. Controller
  4. Constants

So, Create a module pattern which makes these items as public

var MiApp = (function () {
 'use strict';
 
 function constants() {
 
 }
function routes(){
 
 }
function controller(){
 
 }
function factory(){
 
 }
return {
 'factory': factory,
 'routes': routes,
 'controller': controller,
 'constants': constants
 }
});

Now, observe our assumed structure and read the arguments as per our assumed structure. Let's be specific, in any component(factory, routes, controller or constant) the first argument as key and second argument as value.

But for the privacy purpose read the arguments through dynamic argument format instead of formal parameters.

So,

var MiApp = (function () {
 'use strict';
 
 function constants() {
 var key = arguments[0],val = arguments[1];
 }
function routes(){
 var key = arguments[0],val = arguments[1];
 }
function controller(){
 var key = arguments[0],val = arguments[1];
 }
function factory(){
 var key = arguments[0],val = arguments[1];
 }
return {
 'factory': factory,
 'routes': routes,
 'controller': controller,
 'constants': constants
 }
});

now you can create an app like as we assumed before

var app = MiApp()
app.factory('factory_name', ['dependancy1', function(dependacy1){
 
}]);
app.routes('url', 'controller_name');
app.controller('controller_name', ['dependancy1', function(dependacy1){
 
}]);
app.constants('name', function(){
 return {
}
})

Upto now we've just created our required structure only. We didn't implment any feature.
In next article we'll discuss about how to develop these components individually and also concept of dependancy injection.

source here