• 15 heures
  • Facile

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 28/01/2019

Structurez votre code avec des fonctions et du TDD

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Pour l'instant les rôles ne sont pas bien organisés dans nos classes. La classe  Main  ne doit servir qu'à exécuter le lancement. Tout ce qui est relatif aux commandes doit se trouver dans la classe  Order . Or, ici, c'est la classe  Main  qui récupère la saisie de la commande de notre utilisateur.

C'est un mauvais découpage, si un développeur reprend notre code, il aura du mal à comprendre ce que nous avons voulu faire.

Nous allons créer dans la classe  Order  une nouvelle fonction nommée  runMenu.

/**
 * Run asking process for a menu.
 */
public void runMenu() {
}

C'est elle qui va se charger de récupérer la saisie utilisateur à la place de la fonction main.

Pour récupérer une version propre du projet prêt pour ce chapitre vous pouvez importer le projet git suivant : MyMenu - Step 3

Le TDD

Le Test Driven Development est une pratique de développement qui améliore beaucoup la qualité de votre code. En pensant aux tests d'une fonction avant de coder celle-ci on s'assure de penser à tous les cas et surtout d'avoir des tests de grande qualité.

Le TDD consiste  à :

  1. Rédiger en amont les tests pour votre code, en veillant à tester chaque scénario.

  2. Exécuter ces tests et vérifier qu'aucun ne fonctionne.

  3. Écrire le code de la fonction concernée.

  4. Exécuter à nouveau les tests jusqu'à ce que ceux-ci fonctionnent.

Pour cette-fois, j'ai rédigé pour vous le test de  runMenu . Ne vous y habituez pas, bientôt ce sera à vous de le faire. Copiez le test suivant dans la classe OrderTest  sans vous soucier de le comprendre pour l'instant. Il vérifie le bon fonctionnement du programme.

@Test
public void Given_ChikenInStandardInput_When_MenuIsRun_Then_DisplayCorrectProcess() {
    System.setIn(new ByteArrayInputStream("1\n".getBytes()));
    order = new Order();
    order.runMenu();
    String output = outContent.toString().replace("\r\n", "\n");
    assertEquals(output.endsWith("Vous avez choisi comme menu : poulet\n"), true);
    assertEquals(output.length() > "Vous avez choisi comme menu : poulet\n".length(), true);
}

Exécutez-le : le test est rouge ! Il va falloir écrire le code de notre fonction pour qu'il passe au vert.

Pourquoi exécuter les tests pour qu'ils passent au rouge ? On sait déjà que le test ne va pas fonctionner !

C'est pour être certain que votre test vérifie quelque chose. Si le test passe au vert dès maintenant, c'est que votre test n'est pas bon.

Notre nouvelle fonction

Étudions maintenant chaque ligne du code de la  fonction  main  contenue dans notre classe  Main. C'est ce code qu'il va falloir déplacer dans la fonction dans  runMenu .

public static void main(String[] args) {
    Order order = new Order();
    order.displayAvailableMenu();
    Scanner sc = new Scanner(System.in);
    int nb = sc.nextInt();
    order.displaySelectedMenu(nb);
}

Que remarque-t-on avec la première ligne ?

Order order = new Order();

On utilise le mot-clé  new , donc notre  Order  est une variable de type objet ! Vous comprenez maintenant ce qu'est une variable de type objet : un fichier renfermant différentes fonctions. D'ailleurs avec les types objets on parle de méthodes et pas de fonctions.

Les variables de type objet sont souvent représentées visuellement au moyen d'un outil nommé diagramme de classes UML. Ces diagrammes permettent de communiquer plus rapidement entre les développeurs. On voit rapidement comment est structurée une classe. Voici la représentation de  Order  :

Diagramme de classes Order via IntelliJ Utimate
Diagramme de classes Order

Vous comprenez un peu mieux ce qui doit se cacher derrière le type String, non ? 

Ici on va donc, créer une nouvelle variable de type Order.

Peut-il y avoir plusieurs variables de type Order ?

Tout à fait ! Dans notre cas ce n'est pas utile, mais dans le cas de  String  c'est très important. Il peut y avoir beaucoup de chaînes de caractères dans un programme.

order.displayAvailableMenu();

Ici on utilise notre méthode (fonction)  displayAvailableMenu .

Scanner sc = new Scanner(System.in);

Ici on crée une variable de type objet Scanner. La partie entre parenthèses  (System.in)  indique que vous souhaitez récupérer ce que l'utilisateur saisit au clavier. Nous y reviendrons plus tard.

int nb = sc.nextInt();

Avec cette ligne on utilise notre Scanner sc , pour demander un entier à l'utilisateur via le terminal. Puis on place cet entier dans la variable  nb .

order.displaySelectedMenu(nb);

Enfin avec cette ligne, on utilise notre méthode  displaySelectedMenu  pour afficher le bon menu. On lui donne en paramètre la variable  nb  .

Avec ces informations, essayez de modifier votre  Main  et votre  Order  pour faire passer tous les tests au vert.

Voici la solution pour les méthodes  main  et  runMenu  : 

public static void main(String[] args) {
    Order order = new Order();
    order.runMenu();
}
/**
 * Run asking process for a menu.
 */
public void runMenu() {
    this.displayAvailableMenu();
    Scanner sc = new Scanner(System.in);
    int nb = sc.nextInt();
    this.displaySelectedMenu(nb);
}

Relancez les tests, ils sont maintenant verts !

Voici le diagramme de classe UML pour  Order  actualisé :

Diagramme de classes UML avec runMenu via IntelliJ Ultimate
UML avec runMenu

Nous avons terminé avec ce chapitre. Dans le prochain chapitre, nous allons proposer à notre utilisateur de commander un accompagnement et une boisson avec son menu !

Exemple de certificat de réussite
Exemple de certificat de réussite