GitHub LinkedIn RSS
Saturday, November 8, 2014

JavaScript Adapter Design Pattern


Today we'll continue the JavaScript Design Patterns series by discussing the Adapter Pattern. Adapters are added to existing code to reconcile two different interfaces. They allows programming components to work together that otherwise wouldn't because of mismatched interfaces.

Adapter may be also used to ease the use with the existing interface. If the existing code already has an interface that is doing a good job, there may be no need for an adapter. But if an interface is unintuitive or impractical for the task at hand, you can use an adapter to provide a cleaner or more option-rich interface. Let's see how it looks in the following illustration:


Here we depict the example of legacy IDataManager interface, which is deeply used within the system. With the introduction of Redis database into the system, we need an adapter to fill the gaps. Our Adapter class has to implement the getData method, to make it consistent with the system, calling in turn the scan method to iterate over data stored in the database.

The implementation will look something like this:
function RedisDataManager() {
    this.connect = function() {
        console.log('Connect to database');
    };

    this.scan = function() {
        return 'Data from database';
    };
}

function DataManager() {
    this.getData = function() {
        return 'Legacy data';
    }
}
  
function Adapter() {
    var redis = new RedisDataManager();
    redis.connect();
    
    this.getData = function() {
        return redis.scan();
    }
}

function Client(dataManager) {
    console.log(dataManager.getData());
}

var client = new Client(new Adapter());
As you can see our Client is oblivious about the IDataManager implementation, and using the Adapter Pattern, we connect the RedisDataManager to it.

Next time we'll continue our discussion about structural patterns by introducing Bridge Pattern, which is very much alike.
Sunday, November 2, 2014

EcmaScript6 with TypeScript and Grunt.js


ECMAScript 6 is nearly here. In fact I can already taste it and so will you with TypeScript. TypeScript is an open source language and compiler written by Microsoft running on NodeJS. The language is based on the evolving ES6 spec but adds support for types, interfaces that generates JavaScript (ES3 or ES5 dialects based on flag). In fact it's very interesting shift for Microsoft to make something useful for open source community, so before you boo me, have a look at it as it's not so bad.

Introduction


Microsoft has compiled a great video introducing the TypeScript and since one video replaces million words, let's start with it.



Using TypeScript


As TypeScript is built on top of Node.js, installing it will be as easy as breathing.
npm install -g typescript
And compiling the files is done through the tsc command, however this is no way respectable developers work. We'll be using Grunt.js to compile our TypeScript files during the build phase. Let's start with writing something small using the new syntax. As usual all the accompanying code can be found on article's repository. First we'll create Animal class and extend a Lion from it, overriding it's methods.
class Animal {
    constructor(public eats: string) {}

    eat() {
        console.log('Eating ' + this.eats);
    }

    speak() {
        console.log('Animal speaking');
    }
}
///
class Lion extends Animal {
    constructor() {
        super('meat');
    }

    speak() {
        console.log('Lion roars');
        super.speak();
    }
}
Then check our new classes in the HTML file:
<!DOCTYPE html>
<html>
<head>
    <script src="src/Animal.js"></script>
    <script src="src/Lion.js"></script>
    <script>
        var lion = new Lion();
        lion.eat();
        lion.speak();
    </script>
</head>
</html>
Pay attention that we reference the js files and not the ts ones. Now let's move to Grunt.js.

TypeScript and Grunt.js


To make both play together nicely, we'll be needing additional package, called grunt-ts. Since we won't be needing it besides development environment, let's use --save-dev flag to mark our intentions.
npm install grunt-ts --save-dev
Moving on to our gruntfile.js file. I've used as little options as possible to make the example easy to understand. There are a lot of configurations of grunt-ts package, which are thoroughly explained in it's page.
(function () {
    'use strict';
    module.exports = function(grunt) {
        grunt.initConfig({
            ts: {
                dev: {
                    src: ["src/*.ts"]                
                }
            }
        });

        grunt.loadNpmTasks('grunt-ts');
        grunt.registerTask('default', ['ts:dev']);
    };
}());
Once Grunt task is run, four files will be generated including both JavaScript and Map files of our classes. And of course opening our HTML page, will feed the console with following lines:
Eating meat               Animal.ts:5
Lion roars                Lion.ts:8
Animal speaking           Animal.ts:9
Pay attention to where Chrome maps the log calls, which is our original ts files. This will come handy in case of debugging your application, which means you don't really need to open the auto-generated JavaScript files.

Besides support in Visual Studio, TypeScript is also supported in WebStorm and SublimeText. Hope you enjoyed the article and next we'll be talking about CoffeeScript.