Formation Java / Spring Boot pour développeurs COBOL
À l’issue de cette cinquième journée, vous serez être capable de :
structurer le code
méthodes avec paramètres et valeur de retour
List
Map
ArrayList
Les analogies COBOL sont encore un peu présentes, mais commencent volontairement à s’estomper.
En COBOL, un programme bien structuré repose sur :
Exemple classique COBOL :
PERFORM CALCUL-SOLDE PERFORM CONTROLE-DECOUVERT PERFORM AFFICHAGE-RESULTAT
En Java, on vise exactement le même objectif, mais avec :
void
Aujourd’hui, nous allons passer progressivement d’un programme monolithique à un programme structuré.
J’ai conçu le cours de la manière suivante :
Dans ce cours, on abordera les différentes collections et la notion d’interface :
[]
HashSet
HasMap
LinkedList
toString()
On ne pourra pas encore approdondir les notions d’itérateur (Iterator) permettant de parcourir les collections. Nous les verrons ultérieurement.
Iterator
Lien vers les notions de base pour comprendre les Tableaux et les méthodes
Lien vers l’utilisation de Arrays.copyOf() pour manipuler des tableaux
Lien vers les notions de base pour comprendre et manipuler des Collections
Nous pourrions nous poser la question de savoir si c’est une bonne pratique d’avoir écrit jusqu’à maintenant notre code dans la méthode main() !
Un programme Java écrit entièrement dans main() :
main()
Objectifs d’un code structurer :
Syntaxe générale :
typeRetour nomMethode(type parametre1, type parametre2) { // instructions return valeur; // si typeRetour ≠ void }
Premier exemple : la méthode reçoit 2 arguments en paramètres et retourne une valeur de type double.
public double crediter(double solde, double montant) { return solde += montant; }
Second exemple : Même genre de méthode mais en utilisant des objets de type BigDecimal.
static BigDecimal calculerSolde(BigDecimal solde, BigDecimal operation) { return solde.add(operation); }
En COBOL :
CALCUL-SOLDE. ADD OPERATION TO SOLDE.
En Java :
Différences importantes :
Passage par valeur (rappel)
static void modifierValeur(int x) { x = 20; } ... // appel de la méthode depuis une autre méthode (on est dans le main()) int a = 10; modifierValeur(a); // on ne sait pas ce que fait cette méthode de l'entier a // a vaut toujours 10
Avant (code non structuré) dans une méthode main() :
BigDecimal solde = new BigDecimal("1000.00"); for (int i = 0; i < operations.length; i++) { solde = solde.add(operations[i]); if (solde.compareTo(BigDecimal.ZERO) < 0) { System.out.println("DECOUVERT"); } } System.out.println(solde);
Après (code structuré) : On donne une responsabilité à chaque méthode
// le code est dans une méthode static BigDecimal appliquerOperations(BigDecimal solde, BigDecimal[] operations) { for (int i = 0; i < operations.length; i++) { solde = solde.add(operations[i]); } return solde; } // cette autre méthode retourne un booléen pour dire si le compte est à découvert ou pas static boolean estADecouvert(BigDecimal solde) { return solde.compareTo(BigDecimal.ZERO) < 0; }
Déclaration :
BigDecimal[] operations = new BigDecimal[3];
Ou
BigDecimal[] operations = { new BigDecimal("-200.00"), new BigDecimal("150.00"), new BigDecimal("-50.00") };
En pratique, les tableaux sont rarement utilisés seuls dans les applications modernes.
Pourquoi les collections existent ?
Les collections permettent :
import java.util.ArrayList; import java.util.List; List<BigDecimal> operations = new ArrayList<>();
Ajouter des éléments :
operations.add(new BigDecimal("-200.00")); operations.add(new BigDecimal("150.00")); operations.add(new BigDecimal("-50.00"));
Parcourir la liste :
for (BigDecimal op : operations) { solde = solde.add(op); }
Correspondance COBOL : OCCURS + index mais sans taille fixe.
OCCURS + index
Exemple métier : la clé est le numéro de compte et valeur le solde.
import java.util.HashMap; import java.util.Map; Map<String, BigDecimal> comptes = new HashMap<>();
Ajout :
comptes.put("FR001", new BigDecimal("1000.00")); comptes.put("FR002", new BigDecimal("250.00"));
Accès :
BigDecimal solde = comptes.get("FR001");
Correspondance COBOL : table indexée ou fichier clé / valeur
static BigDecimal calculerSoldeFinal(BigDecimal soldeInitial, List<BigDecimal> operations) { BigDecimal solde = soldeInitial; for (BigDecimal op : operations) { solde = solde.add(op); } return solde; }
static int compterDebits(List<BigDecimal> operations) { int compteur = 0; for (BigDecimal op : operations) { if (op.compareTo(BigDecimal.ZERO) < 0) { compteur++; } } return compteur; }
static void afficherSoldes(Map<String, BigDecimal> comptes) { for (String numero : comptes.keySet()) { System.out.println(numero + " -> " + comptes.get(numero)); } }
Objectif : transformer un programme séquentiel en programme structuré
Consignes :
Objectif : mesurer le gain de lisibilité
Objectif : introduire une vision réaliste banque
Consignes : Créer une Map<String, BigDecimal> pour stocker plusieurs comptes
static BigDecimal calculerSoldeFinal(BigDecimal soldeInitial, List<BigDecimal> operations) { BigDecimal solde = soldeInitial; for (BigDecimal op : operations) { solde = solde.add(op); } return solde; } static boolean estADecouvert(BigDecimal solde) { return solde.compareTo(BigDecimal.ZERO) < 0; }
List<BigDecimal> operations = new ArrayList<>(); operations.add(new BigDecimal("-200.00")); operations.add(new BigDecimal("150.00")); operations.add(new BigDecimal("-50.00"));
Map<String, BigDecimal> comptes = new HashMap<>(); comptes.put("FR001", new BigDecimal("1000.00")); comptes.put("FR002", new BigDecimal("250.00")); comptes.put("FR003", new BigDecimal("500.00"));
java.util.List
Aujourd’hui, vous avez :
Décision d’architecture progressive :
Vous savez maintenant :
Le Jour 6 marquera une étape majeure :