vendredi 20 mai 2016

Voilà comment "un cours" devient "une chaîne de caractères"

La conception et la réalisation d'un système quelconque nous pousse à travailler, dans la plus part des cas, avec des niveaux d'abstraction différents. L'idée est de commencer par un niveau élevé d'abstraction et de descendre, étape par étape, vers le niveau physique qui est l'implémentation de la solution. Ce passage n'est pas souple, ni sans risque; une chose qui m'a pris deux années et deux projets pour la réaliser.
Les niveaux d'abstraction sont utilisés depuis les premières approches d'analyse et de conception des systèmes informatiques et des systèmes d'information. Merise, l'une des premières approches, définit trois niveaux d'abstraction :
  • Le niveau conceptuel : le niveau d'abstraction le plus élevé. A ce niveau, on est supposé donner une première modélisation du système en essayant de répondre à la question "Quoi" pour les deux dimensions statique (données) et dynamique (traitements) du système.
  • Le niveau logique (organisationnel) : le deuxième niveau d'abstraction. A ce niveau, on commence à détailler la modélisation donnée au niveau conceptuel en ajoutant les réponses aux questions "Qui" et "Quand".
  • Le niveau physique : le niveau d'abstraction le plus bas; on parle de l'implémentation physique. A ce niveau, la conception (la modélisation) détaillée donnée au niveau logique est traduite à un ensemble de programmes, logiciels, fichiers et bases des données.
Cette définition (très) simplifiée nous montre qu'il est possible de faire une conception et une réalisation souples avec des passages claires entre les différentes étapes. Malheureusement, deux projets durant les deux dernières années ont prouvé que, sous certaines circonstances, c'est pas aussi évident que cela.
En travaillant sur deux projets en e-Learning (comme toujours), les étudiants impliqués ont montré le même comportement malgré que les deux projets étaient complètement indépendants. Le comportement peut être résumé par un constat que me frappait il y a environ deux semaines en essayant d'expliquer à un collègue ce qui ne marche pour le projet en cours : "le cours de l'enseignant est, pour eux, une chaîne de caractère".
Sur ce point, vous allez me dire que c'est normal : toute donnée sera, quelque part durant le processus, traduite vers une donnée binaire pour être implémentée sur la machine. Ainsi, le solde bancaire d'un employé n'est qu'un nombre réel, la valeur d'un crédit qui peut contrôler la vie d'une famille n'est qu'un nombre réel aussi, un avion civil avec des centaines de passagers n'est qu'un cercle de quelques pixels sur un écran et même une déclaration de guerre entre deux pays n'est qu'une chaîne de caractères. Tout cela semble être vrai mais il n'est pas du tout.
Comme étant des humains, nous essayons toujours de donner plus de sens à des évènements qui semblent beaucoup plus simples que ceux cités ci-dessus. Nous tentons, aussi, de détecter des modèles, des lois, des principes et de proposer des théories pour les phénomènes qui nous entourent. En ajoutant ces capacités à nos capacités de manipulation des symboles, nous nous trouvons face à l'intelligence humaine (encore une fois, les définitions sont simplifiées : chaque définition peut nous conduire à écrire un livre entier). Ainsi, au moment où l'enseignant voit son cours comme le fruit d'un effort particulier d'analyse, de résumé et de synthèse, le développeur le voit comme une chaîne de caractères à insérer dans une base des données et à le récupérer plus tard. Ce décalage me semble anormal pour ne pas dire inquiétant pour le projet.
La cause principal, à mon avis, est la mauvaise division des tâches entre les membres de l'équipe, et plus particulièrement, les division de type : "tu fais l'état de l'art et je me charge de ma programmation". Une telle division semble marcher : le résultat finale de la première moitié est un ensemble de schéma descriptifs qui expliquent au moindre détail les composants du système, les traitements à effectuer pour chaque composant et les données à manipuler par chaque traitement. La deuxième moitié du travail consiste à reprendre cette description et à la traduire vers une technologie (niveau physique) pour terminer le projet. Et c'est ce passage qui n'est pas évident : sans suffisamment d'information sur le domaine, les préférences des clients et la nature des besoins, la conception détaillée sera vue par le développeur vide, sans âme et même sans importance particulière. C'est à ce niveau que le cours d'un enseignant et l'adresse d'un apprenant deviennent de la même importance, très similaires et
implémentées de la même façon : une chaîne de caractère.

Un dernier mot

Pour cet article, j'ai fait deux grandes simplifications (ce n'est pas sans risques) en essayant de comprendre ce phénomène qui pousse les étudiants (ou les employés) à vider un projet donné de son sens. L'objectif visé n'est pas de prouver ses origines parce que je ne les connais pas, c'est ma première réflexion sur le sujet. Ce que j'espère est d'exposer ce risque au sein des équipes de développement.

mardi 15 mars 2016

Une approche pour le développement des "petits" projets scientifiques (part. 2)

Au sommaire :



Nous avons terminé la première partie par poser une question très importante : comment choisir le meilleur processus pour un sujet de recherche.
Un sujet de recherche vise, principalement, à vérifier une proposition. Cette dernière est faite après une longue étude théorique, analyse des faits, comparaison, inspiration et adaptation des techniques existantes. Elle peut être très simple ou très complexe, mais, nous pouvons affirmer ce qui suit :

1. Un seul besoin :

Une proposition peut être exprimée comme un seul besoin. Cela ne veut pas dire que l'application doit forcément être de petite taille.
Un seul besoin comme : "l'analyse des traces émotionnelles dans un texte libre" peut être représenté par un seul cas d'utilisation doté d'une interface graphique très simple (une seule fenêtre ou page web qui offre une zone de saisie, un bouton pour lancer le traitement et une zone pour afficher le résultat du traitement), mais, les traitements nécessaires pour réaliser ce traitement peuvent être liés à la Recherche d'information (découpage, nettoyage, pondération, repérage des mots clés émotionnels), au web sémantique (détection des concepts, désambiguïsation, mesure de similarité) ou bien à l'intelligence artificielle (réseaux de neurones).
Un autre besoin comme : "conception et réalisation d'une plate-forme e-Learning basée sur les services web" peut être traduit par un seul besoin  technique mais sa mise en pratique doit passer par la reprise de toute la conception d'une plate-forme e-Learning avec les différents cas d'utilisation, les différentes possibilités d'interface graphique et le résultat est une application relativement complexe. Nous signalons, ici, que le (jeune) chercheur n'est pas obligé de proposer une nouvelle vision et des nouveaux cas d'utilisation pour la plate-forme e-Learning; il peut, d'ailleurs, reprendre une conception existante tout en respectant les droits d'auteur. Il y aura certainement des adaptations et des modifications mais pas une conception "from scratch".

2. Le besoin ne change pas :

Un changement du besoin ne peut être envisagé que si le sujet de recherche lui même a changé. Cela ne provoque pas une modification de l'application mais une annulation de cette dernière. Il faut faire la différence entre un changement dans l'environnement de l'entreprise et un changement de la thématique de recherche : le premier provoque, rarement, un changement radical dans l'entreprise; et même s'il le fait, l'option de reprendre le développement de son système d'information à zéro est toujours envisageable. Le deuxième provoque, généralement, un changement radical parce que il s'agit d'un changement de concept ou de notion traitée ce qui va se répercuter sur toute l'étude théorique ainsi que son implémentation.

3. Pas de séparation entre les besoins techniques et fonctionnels :

Il s'agit d'un seul besoin qui est le besoin principal qui découle directement de l'hypothèse à prouver. Ainsi, la présentation de l'étude théorique et de la partie proposition doit se focaliser sur ce besoin; les autres éléments ne doivent être présentés que dans le mesure du nécessaire.
Reprenons notre exemple sur "le développement d'une plate-forme basée sur les services web". Il est possible d'envisager un processus en cascade ou autre, mais, il sera très dommage si nous ne voyons les services web que pendant les 20 dernières pages (c'est à dire la partie réalisation) sur un la partie conception qui occupe 60 pages ou plus avec toutes ses étapes.

4. Plusieurs itérations ? Difficile à imaginer :

La stabilité de (ou même des besoins si on regroupent tous les éléments de l'application) ainsi que l'absence d'un ensemble de notions supposées être primordiales pour l'entreprise telles que :
  1. Le temps de livraison (délai) : le délai de livraison est un élément essentiel du contrat informatique, néanmoins, cette notion n'a pas cette importance particulière dans un cadre de recherche. Le plus important est le respect de la proposition effectuée et la réalisation des testes suffisants pour prouver l'efficacité (ou pas) de la solution proposée pour déduire par la suite est ce que l'hypothèse effectuée est varie ou pas.
  2. La phase de transition : cette phase est utilisée dans un cadre professionnel pour permettre aux employés de passer progressivement de l'ancien système vers le nouveau système (il est même possible d'envisager une utilisation simultanée des deux systèmes au même temps). Cette phase permet de collecter de nouveaux critiques comme elle représente une occasion idéale pour raffiner et compléter la formation offerte aux employés. Dans un cadre de recherche, l'absence de la notion de production engendre l'absence de la notion de la phase transitoire, ainsi, les utilisateurs sont directement accompagnée par le développeur ou le chercheur pour mener à bien les expérimentations nécessaires sur le système.
  3. La formation des utilisateurs : l'accompagnement des utilisateurs par les membres de l'équipe de recherche est suffisant vu que les données sont collectées à des fins d'expérimentation; faire des erreurs est significatif (l'IHM est inefficace, le système est trop complexe, ces données sont à ignorer - tout simplement, etc.) comme il n'y a pas un risque réel de perte, destruction du système, "arrêt de la production". Ainsi, envisager une formation à part pour les utilisateurs est un investissement coûteux et non justifié.
  4. Les points de contrôle : dans un processus itératif ou même simple, le passage d'une étape à l'autre nécessite une validation de la part du sommet stratégique. Cela se fait par le positionnement de plusieurs points de contrôle tout au long du cycle de développement. Ces points de contrôle se concrétisent par des réunions de validation qui permettent de valider un modèle, de tirer de nouveaux besoins, d'obtenir de nouveaux critique et, le plus important, garder le projet dans la bonne direction. Toutes ces notions ne trouvent aucune projection dans le monde de recherche sauf dans le cadre du laboratoire : travailler sur une nouvelle proposition veut dire l'absence de tout point de référence pour juger la bonne conduite ou pas du sujet; une telle décision ne peut être prise qu'après l'obtention des résultats des différentes expérimentations.
Il est évident que les remarques ci-dessus concernent des cas généraux des projets de recherche en informatique. Ces remarques ne sont, probablement, pas vraies pur d'autres domaines comme elle ne le sont pas pour certains types de projets financé par des budgets particulièrement grands (certainement pas une seule thèse de doctorat ou bien un seul projet de fin d'étude).
En prenant en compte ces caractéristiques, pouvons nous répondre à la question posée précédemment ?

(Pour plus d'informations sur l'auteur et le blog, c'est par ici)

Une approche pour le développement des "petits" projets scientifiques (part. 3)

Au sommaire :



Dans le premier article de cette série nous avons posé une question à laquelle tout (jeune) chercheur doit répondre lorsqu'il entame la concrétisation de sa proposition. Dans le deuxième article, nous avons cité quelques caractéristiques des applications développées dans le cadre des sujets de recherche (thèse de doctorat et mémoire de Master II). Dans cette article, nous allons essayer de répondre à cette question et pourquoi pas pousser les choses un peu plus loin pour faire une autre proposition (qui peut être, comme toute autre hypothèse, vraie ou fausse).
En procédons à un raisonnement par élimination, nous pouvons dire que :
  1. Pour un projet de recherche, une approche itérative n'est pas importante, sauf si la proposition concerne cette approche. Choisir une approche complexe tel que UP, RUP ou XP pour n'exécuter qu'une seule itération, sans avoir de risques qui sont considérés comme le critère de pilotage pour ces approches, sans avoir de complexes cas d'utilisation qui sont considérés comme le centre de ces approches, ne revient qu'à alourdir sans un gain clair le processus de développement.
  2. Pour un projet de recherche, une approche en Y ne peut être appliquée que si on s'amuse à gonfler les besoins et à proposer des besoins marginaux pour l'hypothèse effectuée comme des besoins principaux.
  3. Le prototypage se trouve, à son tour, écarté. Il n'est pas nécessaire de proposer une application insuffisante pour les expérimentations envisagées comme il est important de n'inviter les gens à faire une expérimentation que pour une seule ou deux fois; si vous vous amusez de faire une expérimentation avec chaque prototype proposé , vous allez vous retrouver seul durant l'expérimentation finale (qui est la plus essentielle parce qu'elle utilise l'application complète).
Ainsi, il est justifiable d'opter pour la solution la plus simple et la plus intuitive : le processus en cascade. Cet processus est la forme la plus proche du principe de base qu'est l'approche top-down (l'approche descendante). Ce processus ne fixe aucune règle supplémentaire pour la gestion des équipes, la collaboration, la synchronisation, les problèmes liés aux technologies, les changements des besoins de base et les notions de gestion des projets. Néanmoins, ces notions ne sont pas d'une importance particulière dans le cadre d'un sujet de recherche menée dans le cadre d'une thèse de doctorat ou moins encore dans un projet de fin d'étude en Master II.
Poussons notre raisonnement un peu plus loin. L'approche en cascade reste toujours destinée pour des projets d'une taille remarquable. La richesse des modèles de description utilisée permet de garantir une communication correcte et efficace entre les différentes équipes impliquées dans le projet, elle peut aussi inclure une dimension décisionnelle. Nous posons ainsi la question : peut on simplifier encore le processus de développement pour ne prendre que la définition de base de l'approche top-down d'une manière suffisante pour les applications relativement petite ?

(Pour plus d'informations sur l'auteur et le blog, c'est par ici)

Une approche pour le développement des "petits" projets scientifiques (part. 4)

Au sommaire :



Dans le dernier article, nous avons déduit que l'approche simple (en cascade) est suffisante pour un projet de recherche et d'une manière justifiée. Nous avons terminé l'article par une nouvelle question : "peut on simplifier encore le processus de développement pour ne prendre que la définition de base de l'approche top-down d'une manière suffisante pour les applications relativement petite ?"
Dans cet article, je vais parler d'un modèle de développement très efficace et très puissant qui existe depuis des millions d'année et qui peut être adapté pour être appliqué sur le développement des applications en informatique.
Je vais reprendre un passage de Wikipedia (les autres sources que je dispose sont protégés alors que ce passage est sous licence Creative Commons, en plus il est suffisant parce que nous ne voulons pas entamer des points spécialisés ou avancés) :
"La différenciation au cours du développement
Le développement commence lorsqu'un spermatozoïde féconde un ovule et crée une seule cellule qui peut potentiellement former un organisme entier. Dans les premiers jours qui suit la fécondation, cette cellule-œuf se divise en plusieurs cellules identiques. Chez l'homme, environ quatre jours après la fécondation et après plusieurs cycles cellulaires, ces cellules commencent à se spécialiser et forment une sphère creuse appelée blastocyste. Celui-ci possède une couche de cellules externes (les cellules périphériques ou trophectoderme) et un groupe de cellules internes, appelées cellules de la masse interne. Ce sont ces cellules qui formeront tous les tissus du corps humain. Malgré cela, elles ne peuvent plus individuellement former un organisme entier : elles sont qualifiées de pluripotentes. Ces cellules continuent ensuite à être progressivement déterminées jusqu'à donner des cellules souches qui donneront des cellules de types bien définis. Par exemple, les cellules souches du sang situées dans la moelle osseuse produisent des hématies, des leucocytes et des plaquettes."


De toute cette partie, nous nous intéressons au principe de spécialisation. Ce principe permet d'obtenir un nouveau organe, c'est que vous dire pour nous une nouvelle forme, plus spécialisée en partant d'une seule cellule au départ. Cette dernière contient toutes les informations nécessaires, c'est à dire, elle est vivante et active (fonctionnelle) mais elle se divise et se spécialise pour pouvoir construire un système plus complexe et plus efficace. Cette construction se base sur la construction de plusieurs organes spécialisés et de garantir la complétude, la communication et la coordination entre ces différents organes.
Ce principe peut, à mon avis, être la base pur une formalisation d'une approche utilisée depuis le début de l'informatique mais d'une manière informelle.
Pour pouvoir continuer, il est nécessaire de retenir deux idées de base :
  1. La cellule de départ contient toutes les informations nécessaires,
  2. Le principe de spécialisation donne naissance à de nouveaux organes qui se concentrent sur une seule tâche.


(Pour plus d'informations sur l'auteur et le blog, c'est par ici)

Une approche pour le développement des "petits" projets scientifiques (part. 5)

Au sommaire :



Le dernier article était plus proche d'un cours en biologie mais il peut faire sujet d'une bonne adaptation. Je rappelle les deux points à retenir :
  1. La cellule de départ contient toutes les informations nécessaires,
  2. Le principe de spécialisation donne naissance à de nouveaux organes qui se concentrent sur une seule tâche.
Ces deux points peuvent constituer le début d'une approche descendante, rapide, efficace et bien formalisée mais limitée (dans un première temps) à des systèmes de recherche d'une taille relativement réduite.
Nous pouvons proposer l'adapation suivante :
Le développement du système commence par la construction d'un seul programme fonctionnel qui exécute le traitement dans sa forme la plus basique (sans cas d'utilisation et sans données complexes) : le programme en question ne doit pas définir des objets du système ou de créer des modules, mais, il consiste en un traitement de base sans des structures complexes de données. L'élément le plus important est qu'il soit fonctionnel pour le cas choisi. Ce dernier doit être un cas général sans caractéristiques particulières comme il ne doit pas être un cas particulier.
Chaque partie du traitement est reprise dans un "organe" (fonction, objet) créant séparément selon sa spécialisation. A ce niveau, il est possible de se concentrer sur ce nouveau organe et de le raffiner en traitant les cas particuliers. Il est aussi important de penser à ajouter des "organes" pour gérer les entrées et les sorties.
De ce point, nous pouvons penser à plusieurs améliorations possibles telles que :
  1. Affaiblir le couplage en ajoutant des interfaces entre les différents parties du systèmes,
  2. Ajouter un niveau de configuration pour permettre une meilleure gestion du couplage des différentes partie.
Il est clair que ces deux dernières propositions sont déjà présentes dans le domaine informatique et elles sont utilisées par plusieurs technologies présentes sur le marché. Le point que je veut expliquer est qu'il est possible de produire un processus tiré directement du processus biologique mais qui est mieux adapté et plus performant dans le cadre du génie-logiciel.
Il est évident que cette proposition est loin d'être complète, cela pourra prendre un mémoire entier pour présenter les différents aspects théoriques, faire une étude comparative, analyser au mieux le processus biologique pour enfin construire une proposition complète, néanmoins, cela peut être encourageant à utiliser une telle approche simplifiée pour les projets de "petite" taille (cela nécessite aussi une quantification) et d'avoir suffisamment d'arguments en cas où on est amené à défendre un tel choix.
J'insiste, aussi, sur un point très important : cette approche proposée peut apparaître comme un processus évolutif tel que le prototypage, néanmoins, elle est sur un niveau technique contrairement aux notions et aux étapes définies par les processus évolutifs, ces notions que j'ai repris une partie dans les premiers articles de cette série.
Dans le dernier article, je vais donner un exemple en Java qui démontre les concepts présentés dans cette série.
Dans cet article, nous allons essayer de développer un système (si on veut dire) qui calcule la somme de deux entiers (de "petite" taille comme j'ai dit).
Notre objectif principal est de calculer la somme, ainsi, le programme le plus simple commence par l'initialisation de deux variables, calculer la somme et mettre le résultat dans une troisième variable, et enfin, afficher le résultat :



public class CalculerSomme{
 public static void main(String args[]){
  int a = 10;
  int b = 20;
  
  int s = a + b;
  
  System.out.println("La somme est : " + s); 
 } 
}


Nous remarquons que le programme se divise en trois parties principales :
  1. Récupérer les valeurs des paramètres,
  2. Faire le calcul,
  3. Rendre le résultat.
Ainsi, pour une première spécialisation, nous allons créer un objet pour chacune des trois parties.
Les entrées :


import java.util.Scanner;

public class Entree{

 Scanner lectureClavier;
 public Entree(){
  lectureClavier = new Scanner(System.in);
 }
 
 public void chargerParametres(){
  CalculerSomme.a = lectureClavier.nextInt();
  CalculerSomme.b = lectureClavier.nextInt();
 }

}


Les sorties :


public class Sortie{
 public void afficher(String message){
  System.out.println(message);
 }
}



Le calcul :


public class Calculette{
 int a;
 int b;
 int s;
 
 public Calculette(int a, int b){
  this.a = a;
  this.b = b;
 }
 
 public void executer(){
  s = a + b;
 }
 
 public int obtenirResultat(){
  return s;
 }
}



Le programme principal devient plus simple, il devient le contrôleur principal parce qu'en réalité il ne fait que appeler et coordonner entre les autres objets, il n'effectue aucun traitement :


public class CalculerSomme{
 
 public static Entree e;
 public static Sortie s;
 public static Calculette c;
 
 // Les paramètres
 public static int a;
 public static int b;
 
 public static void main(String args[]){
  e = new Entree();
  s = new Sortie();
  
  e.chargerParametres();
  
  c = new Calculette(a, b);
  c.executer();  
  
  s.afficher("Le résultat est : " + c.obtenirResultat());
 }
}



C'était l'idée de base, mais nous pouvons continuer plus loins : pourquoi ne pas ajouter des interfaces. La déclaration des différents objets utilise les interfaces et non pas les noms des classes directement, tout le reste (instantiation et appel :
Interface pour sortie :


public interface ISortie{
 public void afficher(String message);
}


Interface pour entrée :


public interface IEntree{
 public void chargerParametres();
}


Interface pour Calculette :


public interface ICalculette{
 public void executer();
 public int obtenirResultat();
}


La déclaration dans le programme principal :


public static IEntree e;
 public static ISortie s;
 public static ICalculette c;


Un faible couplage nous permet d'étendre facilement notre système en proposant différents "organes" pour la même fonctionnalité. Pour notre exemple, nous allons ajouter deux classes de sortie et d'entrée qui respectent les interface définies et qui sont dotées d'une interface graphique :
La fenêtre d'entrée :


Le message de sortie :



Le programme principal se dote d'une configuration pour les différents cas possibles : exécuter dans la ligne de commande et exécuter en utilisant l'interface graphique.

A la fin de cet exemple, je veux insister sur quelques points :
J'ai pas gardé l'appellation standard en Java (set, get, etc.), j'ai  voulu garder tout le contenu dans une seule langue,
Il est claire qu'il est possible d'optimiser mieux le code source ou le passage de paramètres; cet exemple est pour illustrer l'idée, ainsi, j'essaie d'oublier que je travaille sur un A+B et d'imaginer que le nombre de paramètres et un peu plus grand,
La proposition faite est loin d'être complète : le passage de paramètres et des messages n'est pas bien défini.

(Pour plus d'informations sur l'auteur et le blog, c'est par ici)

lundi 14 mars 2016

Une approche pour le développement des "petits" projets scientifiques (part. 1)

Au sommaire :



La plupart (pour le pas dire toutes) des processus de conception et de réalisation définies en génie-logiciel se basent sur l'une des deux approches :

1. L'approche ascendante (ou l'approche bottom-up) :

En optant pour cette approche, vous procédez à construire votre système en partant de plusieurs parties plus petite. Cette approche peut être retrouvée, à titre exemple, dans :
  1. La conception d'une base des données en se basant sur les dépendances fonctionnelles : dans ce cas, une dépendance fonctionnelle est vue comme une partie, le schéma global de la base des données est constuit en combinant, nettoyant et regroupant les différentes dépendances fonctionnelles. Le processus principal est l'algorithme de la couverture minimale (qui utilise, à son tour, l'algorithme de la fermeture transitive).
  2. La programmation orientée composants : dans ce cas, un composant est vu comme une partie du système, l'application finale est le résultat d'une combinaison (couplage) entre les différents composants. Les composants sont, généralement, disponible dans un entrepôt des composants et il est possible de choisir un parmi les différents processus proposés pour procéder à la sélection des composants adéquats aux besoins visés par l'application.
Parmi les différentes approches basées sur les composants, nous trouvons l'approche des services web et ses annuaires UDDI qui permettent de localiser et d'invoquer des services web existants pour construire une nouvelle application (composition par orchestration ou par chorégraphie).

2. L'approche descendante (ou approche top-down) :

C'est la proche la plus utilsiée vu qu'il n'est pas possible (pour des raisons d'existance, d'incompatibilité, du coût ou pour autres raisons) d'obtenir les composants de base pour construire un système. Cette approche part de l'ensemble des besoins (fonctionnels et techniques) et tente de découper le système à des sous-systèmes qui seront à leur tour décupés à des sous-sous-sytème pour arriver, enfin, à un niveau où la réalisation est faisable. Cette approche était l'approche intuitive et logique au début de l'informatique et le premier processus proposé (le processus en cascade) n'est qu'une formalisation directe de cette approche. le processus en cascade commence par la définition des besoins, ensuite, chaque besoin est analysé pour donné lieu à une conception abstraite puis une conception détaillée (le nom dit tout !). Cette approche est très visible dans le cas des approches proposées aujourd'hui, surtout celles basées sur le langage UML (UP, XP, Y) : le diagramme des cas d'utilisation prémordial et utilisé par toutes ces approches n'est qu'un premier découpage du système à un ensemble de "processus ou modes d'utilisation".
Cette approche fait l'objet de cet article. En effet, les différents processus en génie-logiciel proposent des solutions pour les différents problèmes rencontrés au niveau des entreprises.
Les premiers processus itératifs proposées visaient à répondre à la problématique du changement des besoins fonctionnels du système à construire. L'environnement dynamique de l'entreprise ainsi que les changements nécessaires à sa survie rendent les besoins fonctionnels temporaire (en quelque sorte) : changements des procédures, adaptation à des nouvelles lois, apparition des besoins d'interopérabilité, ainsi que des dizaines de possibilités qui poussent les concepteurs à revoir leur conception et par la suite la partie à modifier du logiciel.
Les processus en prototypage visent à régler un autre type de problème : réduire au maximum le temps de livraison. Un système qui garantit plusieurs fonctionnalités peut être lourd à implémenter, ainsi, pourquoi en pas livrer une partie du système à la fois, par conséquent, les équipes de conception et de réalisation peuvent se concentrer sur cette partie ("petite" par rapport à la taille du système finale). Le processus est répété selon le nombre des fonctionnalités à implémenter et chaque itération donne naissance à une nouvelle partie du système et qui sera directement intégrée à l'application qui est déjà en cours d'utilisation.
Le processus en Y, partiellement itératif (ou semi-itératif) vise à régler un autre type de problème : la prise en compte de la dimension technique. Les premiers processus en génie-logiciel passaient par les quatre niveaux d'abstraction (vues extérieures, niveau conceptuel, niveau logique et niveau physique) du niveau le plus abstrait vers le niveau physique, ainsi, les choix techniques étaient généralement pris après la fin de la conception (ce qui permettait, d'ailleurs, de choisir les meilleures technologies pour la conception effectuée). Cette approche est encore possible lorsqu'il s'agit d'une première automatisation du système d'information, mais, elle devient lourde si le système (ou l'application) à construire doit respecter un ensemble de choix techniques déjà pris par les premiers systèmes développés dans l'organisation. Ainsi, pour une prise en compte explicite de ces besoins dits techniques nous devons faire recours au processus de développement en Y.
La question que nous devons poser à la fin de cette première partie est la suivante :
Qu'elle est le meilleure processus (ou approche) à utiliser pour développer une application dans le cadre d'un sujet de recherche ?


(Pour plus d'informations sur l'auteur et le blog, c'est par ici)

mercredi 2 mars 2016

Enseigner l’algorithmique pour les débutants .. Deux solutions pour le même problème


Une analyse de la situation actuelle à l’université algérienne peut nous amener à conclure que l’enseigner l’algorithmique est une responsabilité. En effet, les étudiants en 1ère année universitaire n’ont pas encore tranché pour leur future, ils ont, seulement, choisi l’option MI : Mathématiques et Informatique. Ce tronc commun est destiné aux matheux ayant plus de 12 comme note de mathématiques en BAC. Avec l’invisibilité qui règne sur le future de tout jeune algérien, la plus part des étudiants en 1ère année hésitent encore entre suivre un parcours en Mathématiques ou opter pour une carrière en Informatique. L’Algorithmique peut être le module clé pour pousser l’étudiant à l’une des deux possibilités.
Prenons un exemple utilisé généralement pour aider les étudiants à comprendre et à travailler sur les matrices : la deuxième diagonale d’une matrice carrée. Cette diagonale peut être présentée dans différents exercices tels que le carré magique.



En se basant sur l’évolution du cours, nous allons probablement se trouver avec une analyse de passage entre les deux cellules voisines pendant le parcours de cette diagonale :

Ainsi, l’algorithme sera du genre (en prenant “i” comme indice de ligne, “j” comme indice de colonne et N la taille de la matrice) :

i := 1;
j := N;
TQ (i <= N) Faire
     {Notre traitement}
     {La cellule actuelle est accessible par M[i, j]}
     i := i + 1;
     j := j - 1;
FinTQ

Est ce la meilleure solution ? Si on prend le temps d’exécution et l’espace mémoire, la réponse sera Non. Nous pouvons proposer une deuxième solution en partant de l’affirmation suivante (ou de la remarque intuitive, si vous voulez) suivante :
Lorsque i est incrémenté par 1, j est décrémenté par la même valeur”
Une petite adaptation rapide peut, vite, amener l’étudiant à proposer l’algorithme de la forme :

i := 1;
TQ (i <= N) Faire
    {Notre traitement}
    {La cellule actuelle est accessible par M[i, N - i + 1]}
    i := i + 1;
FinTQ

En d’autres termes, le j est écrit en fonction de i et on gagne deux (ou quatre) octets en mémoire centrale.
Pour un développeur, ou même un étudiant en 2ème année, cette solution paraît très simple et même la solution logique, mais pour un étudiante en 1ère année, les choses diffèrent.
Le problème ne réside pas dans la formule de j en fonction de i (le N - i + 1); une fois demandé, les étudiants arrivent souvent à la trouver facilement en partant du fait qu’on parle d’une symétrie par rapport au centre de la matrice :
(i + j) / 2 = (1 + N)/2
i + j = 1 + N
j = N - i + 1
Le vrai problème réside dans cette sensation qui pousse l’étudiant à penser qu’il est possible d’écrire j en fonction de i et de gagner quelques octets en mémoire centrale. Notre enseignant M. B. Chergou (page perso) faisait référence à cela par dire que c’est la partie “génie” dans “ingénieur”, une affirmation encourageante pour des étudiants qui ont déjà choisi “ingénieur en informatique” comme carrière. Cette même affirmation ne peut pas, forcément, avoir le même effet sur des étudiants 1) en licence, 2) n’ont pas encore fait leur choix et 3) se sentent dans l’insécurité.
Pendant une séance de Travaux Dirigés, on peut être amené à présenter l’une des deux solutions; pas seulement pour cet exemple, mais pour dans les différents cas les différents exercices un peu plus compliqué que le calcul de la somme de deux entiers. La solution présentée dépendra, probablement, des éléments les plus actifs pendant cette séance. Elas, un risque se présente : présenter la deuxième solution au problème, sans donner la possibilité aux étudiants, qui n’ont pas eu l’intuition de la détecter, de voir d’autres possibilités va les laisser derrière; répétez la même chose pendant deux à trois séances, et je peux vous garantir que vous aller continuer avec le même groupe qui a fait cette intuition pendant que les autres vont peu à peu abandonner le module en le voyant comme un module intuitive, non méthodique et même poétique (n’oubliant pas qu’il s’agit des matheux).
A mon avis, il est très important d’opter pour la première solution; la solution méthodique, sans ajouter les contraintes d’optimisation sur les étudiants et de présenter la deuxième solution par la suite comme un raccourcis qui peut être emprunté (ou pas). Ainsi, l’aspect “exacte” de l’algorithmique et de la programmation de manière générale restera préservé et les étudiants seront (pour le moment) protégés d’avoir l’impression que la programmation est basée des capacités d’observation particulières ou nécessite une intelligence spéciale.

P.S : Cet article est fait suite à un constat réel qui dépend (comme les sciences sociales le précisent) de l’échantillon des étudiants, la succession des évènements et le contenu du cours et des travaux dirigés présentés. Un tel problème ne sera pas, probablement, rencontré si les étudiants ont déjà fait des travaux de programmation (tous les étudiants) (Cours CS 106 - U. Stanford)