Libellés

dimanche 14 août 2011

Javascript et les objets : héritage, prototype, constructor, ...


Javascript n'est pas un langage orienté objet, mais à l'aide des
prototypes nous pouvons quand même nous en sortir.


### Création d'un objet

Le Js est un langage fonctionnel, ce qui signifie que les fonctions
sont au centre du langage. Et donc, pour créer l’équivalent d'une
classe en js, nous allons commencer par créer son constructeur : une fonction.

   var myClass = function(){
     this.name = 'Romain';
   }


Puis ensuite nous allons instancier cet objet :

   var o = new myClass();
   console.log(o.name);


L'instanciation va se dérouler en plusieurs étapes. Tout d'abord un
objet o tout vide va être créé. Ensuite le constructeur myClass va
être appelé sur cette objet. Le this.name va permettre de créer
l'attribut name dynamiquement.


### Le prototype

Le prototype est le dénominateur commun entre toute les instances d'une même classe.

Si j'ajoute un attribut(ou une méthode) sur le prototype de myClass, alors cet attribut (ou méthode) sera present sur toute les instances de myClass.

   myClass.prototype.age = 25;
  
   console.log(o.age);



### Lien entre le prototype et le constructor.

Comme nous l'avons vu tout à l'heure myClass est une fonction qui va permettre de créer l'objet. C'est le constructeur.

  console.log(typeof myClass) //function


A partir de cette fonction nous pouvons accéder au prototype :

  console.log(myClass.prototype) //{ age: 25 }



Et à partir du prototype nous pouvons retrouver le constructeur. Ce qui signifie qu'à partir de n'importe quel objet, nous pouvons retrouver le constructeur car comme nous l'avons vu précédemment toutes les methodes et attributs d'un prototype sont accessible dans les instances.

   console.log( myClass.prototype.constructor === myClass)
   console.log( o.constructor === myClass)



### L'héritage en javascript

Comme chaque instance hérite de son prototype, il suffit de chainer les prototypes pour faire de l'héritage.

Voici un exemple complet :

    /*
     * On créé le constructeur de l'objet A.
     * Ce constructeur va ajouter automatiquement un attribut name à l'objet.
     */
    var A = function(){
      this.name="Romain";  
    };

    A.prototype.sayHello = function(){
       return "Hello "+this.name;  
    };

    /* On fait de même pour l'objet B */
    var B = function(){
      this.age= 25;  
    };

    /* Maintenant on dit que B hérite de l'objet A */
    B.prototype = new A();

    /* Pour ne pas perdre la référence vers constructeur de B */
    B.prototype.constructor = B;


    /* On vérifie que ça marche */
    var o = new B();
    console.log(o.name);             //Romain
    console.log(o.age);              //25
    console.log(o.sayHello());       //Hello Romain
    console.log(o instanceof B);     // true
    console.log(o instanceof A);     //true
    console.log(o instanceof Object);//true

    /* Et pour le fun, on vérifie que les constructeurs sont logiques */
    console.log(B.prototype.constructor === B);  //true
    console.log(A.prototype.constructor === A);  //true


    /* On peut même recréer un objet à partir d'un autre */
    var p = new o.constructor();
    console.log(p.name);  //Romain
    console.log(p.age);   //25

samedi 13 août 2011

Jaxrs client avec Jersey

Ce n'est souvent pas évident de trouver un client Jaxrs. Jersey vous en propose un, et voici comment l'utiliser.  Par défaut j'ai rajouté les logs des requêtes HTTP :


  @Grab('com.sun.jersey:jersey-client:1.8')
  @Grab('com.sun.jersey:jersey-core:1.8')
  @Grab('com.sun.jersey.contribs:jersey-apache-client4:1.8')

  import com.sun.jersey.api.client.*;
  import com.sun.jersey.api.client.filter.LoggingFilter;
  import javax.ws.rs.core.*;
  import com.sun.jersey.client.apache4.ApacheHttpClient4;

  Client client = ApacheHttpClient4.create();
  client.addFilter(new LoggingFilter());
  def resource = client.resource("http://geek-du-soir.blogspot.com").path("/feeds/posts/default")
  resource.accept("application/xml+atom").get(String.class);

jeudi 11 août 2011

Logguer les requettes HTTP de Jersey Client

Pour logguer les requêtes HTTP éffectuées par Jersey Client il suffit de rajouter :

client.addFilter(new LoggingFilter());


Voici un exemple complet :


@Grab('com.sun.jersey:jersey-client:1.8')
@Grab('com.sun.jersey:jersey-core:1.8')
@Grab('com.sun.jersey.contribs:jersey-apache-client4:1.8')

import com.sun.jersey.api.client.*;
import com.sun.jersey.api.client.filter.LoggingFilter;
import javax.ws.rs.core.*;


Client client = create();
client.addFilter(new LoggingFilter());
def resource = client.resource("http://geek-du-soir.blogspot.com").path("/feeds/posts/default")

resource.accept(MediaType.APPLICATION_XML).get(String.class);



import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLSocketFactory;
import com.sun.jersey.client.apache4.ApacheHttpClient4;
import com.sun.jersey.client.apache4.config.DefaultApacheHttpClient4Config;

ApacheHttpClient4 create() {
DefaultApacheHttpClient4Config config = new DefaultApacheHttpClient4Config();
ApacheHttpClient4 jerseyClient = ApacheHttpClient4.create(config);
HttpClient httpClient = jerseyClient.getClientHandler().getHttpClient();
SSLSocketFactory sf = (SSLSocketFactory) httpClient.getConnectionManager().getSchemeRegistry().getScheme("https").getSchemeSocketFactory();
sf.setHostnameVerifier(new AllowAllHostnameVerifier());
return jerseyClient;
}

mercredi 10 août 2011

getter et setter avec nodeJs : EcmaScript 5


NodeJs permet d'écrire du code en ECMA Script 5, nous pouvons donc profiter des getter et setter :


/*jslint es5: true */

function MyClass() {
    var name;

    return {
        get name() {
            return name;
        },
        set name(value) {
            name = 'Mr ' + value;
        }
    };
}

var obj = new MyClass();

obj.name = "Romain";   //call the setter
console.log(obj.name); //call the getter

/* print 'Mr Romain' */

mardi 9 août 2011

Commencer nodeJs avec npm, cloud9 et vows sur Archlinux

J'ai la chance de pouvoir tester nodeJs actuellement, je vais donc essayer de vous en faire profiter via mon blog.

Si vous êtes sous windows passez votre chemin. Désolé :-)

Pour les utilisateurs de Linux, je vais surtout vous expliquer comment j'ai installé mon environnement de développement sous Archlinux, mais il est également assez facile de le faire avec Ubuntu (via les ppa)


### Installer nodeJs

NodeJs est le JsDK basé sur le moteur javascript V8 de google, qui vous permettra de coder vos applications en JavaScript.

Contrairement à Java, nodeJs démarre très vite et ne prend pas beaucoup de RAM. C'est très agréable !!!

Le paquet nodejs se trouve dans community, pour l'installer il vous suffit donc de tapper :

pacman -S nodejs

### Installer npm

NPM comme node package manager, correspond au maven java, au gem ruby, ... c'est le gestionnaire de paquet.

Npm se trouve sur AUR, si vous avez yaourt vous pouvez l'installer comme ceci :

yaourt -S nodejs-npm


### Installer cloud9

Cloud9 est un IDE node réalisé en node. C'est un exemple vivant de ce que l'on peut faire avec nodeJs. Je vous conseil de l'installer rien que pour ça.

Le paquet AUR de cloud9 est moins bien conçu que les autres (mais cloud9 n'est simplement pas évident à installer)

yaourt -S cloud9

Puis éditer le PKGBUILD pour appliquer ce patch :

git clone $gitroot $gitname
cd $gitname
- git checkout $gittag
+ #git checkout $gittag
git submodule update --init --recursive


For x86 users, the build fails. You have to remove the 64 bit files :

package() {
+ find -name *linux64* | while read file; do
+ rm $file
+ done
install -d $pkgdir/opt/cloud9


### Installer vows

Vows est la librairie de test nodeJs. Il permet d'écrire des specifications de son code au format bdd. Pour plus d'info : http://vowsjs.org/

Pour l'installer sur votre système, il faut maintenant se reposer sur npm. C'est npm qui va se charger d'installer vows dans /usr

sudo npm install -g vows

sudo pour lui donner les accès root
-g pour qu'il l'installe dans /usr/bin/vows


### Démarrer cloud9

Cloud9 est un serveur web, vous accéderez à l'IDE via votre navigateur web, cool n'est-ce pas :) Et en plus c'est plus léger qu'un IDE lourd !

Bien évidemment Cloud9 n'est actuellement pas l'équivalent de Netbeans mais il propose déjà des corrections de syntaxe, la coloration syntaxique, la mise en forme automatique du code, une console et un debugger (qui ne marche actuellement pas chez moi).

Le meilleurs IDE Js est à mon avis IntelliJ mais il est payant. Sinon NetBeans fonctionne plutôt bien.

Pour lancer cloud9, il faut se placer dans le répertoire de son projet js et lancer la commande :

$ cd myProject
$ cloud9 &
...
Point your browser to http://127.0.0.1:3000


### Premier projet js

Créons la structure du projet :

$ touch index.js #main file
$ mkdir lib/ #sources
$ mkdir test/ #tests


Créons notre premier module :

$ cat lib/Playground.js

//Je déclare un classe, qui sera instanciée en tant qu'objet plus tard
function myClass(){
this.name= "Romain";
this.age=25;
this.getAge= function(){ return this.age; };
this.setAge= function(age){ this.age=age; };
}

//Puis je l'exporte pour pouvoir l'utiliser dans mes tests et dans mon projet
exports.myClass = myClass;



Et le test associé :

var vows = require('vows'),
assert = require('assert'),
playground = require('../lib/Playground');

var myClass = playground.myClass;

vows.describe('play with prototype').addBatch({
'given an object': { //je commence ma description au format BDD
topic: new myClass(), //topic sera l'objet de mon test

'when age is changed': {
topic: function (obj) { //obj === topic
obj.setAge(20);
return obj; //et je redéfinie topic pour qu'il reste === obj
},

'then I get the new age': function (obj) {
assert.equal(21, obj.getAge());
}
}
}
}).exportTo(module); //obligatoire pour utiliser vows comme cli.


Et maintenant si on run vows (soit via cloud9, soit via le cli) :

$ vows test/*.js

given an object when age is changed
✗ then I get the new age
» expected 20,
got 21 (==) // TestPlayGround.js:18

✗ Broken » 1 broken (0.015s)

Sympa le format de sortie :)