Explication de la décomposition du TP2

  1. La couche "présentation" : la page HTML et la feuille CSS
  2. La couche "coordonnateur" : cette couche fait la médiation entre la couche "présentation" et la couche "métier"
  3. La couche "métier" : encapsule la logique relative au fonctionnement de la caisse

Petit schéma explicatif


MVC_a.png
  1. La couche présentation génère un événement suite à une action de l'utilisateur, cet événement est capté par le coordonnateur.
  2. Le coordonnateur, en fonction de l'événement capté, appelle une fonction de la couche métier.
  3. Le résultat de la fonction est reçu par le coordonnateur.
  4. Le coordonnateur transmet le résultat à la couche présentation qui l'affiche.

Quelques principes de base de la conception

  • Couplage faible : il y a couplage entre des modules lorsqu'une modification à un module entraine plusieurs modifications aux autres modules
  • Cohésion forte : un module possède une cohésion forte s'il ne fait qu'une seule chose, s'il est ciblé sur une seule tâche
  • Niveau d'abstraction homogène : la cohésion forte implique souvent que le module traite des concepts d'un seul niveau (par exemple, un module peut gérer les contrôle de bas niveau de l'interface personne-machine ou un module peut gérer les calculs financiers, mais un module qui traiterait les deux ne respecterait pas un niveau d'abstraction homogène)
  • Séparation des problèmes (separation of concerns) : la devise "Diviser pour régner" s'applique en informatique en réduisant un problème en plusieurs problèmes plus petits et plus ciblés.

Étude de la fonction génératrice de nombre au hasard : Math.random()

var assert = require( 'assert' );
 
// Générer un nombre au hasard entre 0 et 1
 
Math.random();
 
// Générer un nombre entier entre borneInferieure et borneSuperieure (borneInferieure et borneSuperieure inclus)
 
function randomEntier( borneInferieure, borneSuperieure ) {
    if ( borneInferieure !== Math.floor( borneInferieure ) ) {
        throw new Error( "Le premier paramètre n'est pas un entier" );
    }
    if ( borneSuperieure !== Math.floor( borneSuperieure ) ) {
        throw new Error( "Le deuxième paramètre n'est pas un entier" );
    }
    if ( borneInferieure >= borneSuperieure ) {
        throw new Error( "Le premier paramètre est égal ou supérieur au deuxième" );
    }
    var intervalle = borneSuperieure - borneInferieure;
    return Math.floor( Math.random() * ( intervalle + 1 ) ) + borneInferieure;
}
 
// Tester la validation des paramètres
 
assert.throws( function(){ randomEntier( 1.5, 2 ) }, /premier .* pas un entier/ );
assert.throws( function(){ randomEntier( 1, 2.5 ) }, /deuxième .* pas un entier/ );
assert.throws( function(){ randomEntier( 1, 1 ) }, /égal ou supérieur/ );
assert.throws( function(){ randomEntier( 2, 1 ) }, /égal ou supérieur/ );
assert.doesNotThrow( function(){ randomEntier( 1, 2 ) } );
 
// Construire une table des fréquences
 
function calculerFrequences( fonction, nombreFois ) {
    var frequences = {};
    var i;
    var resultat;
    for ( var i = 0; i < nombreFois; i++ ) {
        resultat = fonction();
        if ( frequences[ resultat ] ) {
            frequences[ resultat ] += 1;
        } else {
            frequences[ resultat ] = 1;
        }
    }
    return frequences;
}
 
// Tester pour des dés
 
var lancerDe = function() {
    return randomEntier( 1, 6 );
}
 
var frequences = calculerFrequences( lancerDe, 10000 );
 
console.log( frequences );
 
// Pile ou face
 
function pileOuFace() {
    return randomEntier( 0, 1 ) ? "pile" : "face";
}
 
console.log( calculerFrequences( pileOuFace, 10000 ) );