• Aucun résultat trouvé

IFT 1015 - Art de programmer 2

N/A
N/A
Protected

Academic year: 2022

Partager "IFT 1015 - Art de programmer 2"

Copied!
43
0
0

Texte intégral

(1)

IFT 1015 - Art de programmer 2

Professeur:

Stefan Monnier

B. K ´egl, S. Roy, F. Duranleau, S. Monnier

D ´epartement d’informatique et de recherche op ´erationnelle Universit ´e de Montr ´eal

hiver 2006

(2)

Au programme

Modularit ´e, coh ´esion, couplage d’une m ´ethode

Modularit ´e des classes

Tester une m ´ethode

(3)

Rappel: pourquoi les m ´ethodes?

Avantages:

Eviter la r ´ep ´etition´

=

r ´eutilisation du code Premier niveau d’abstraction

Programme plus simple `a comprendre Faciliter la d ´etection/correction d’erreur Facilite le travail d’ ´equipe

Ces avantages sont garantis?

Non! Il faut savoir bien ´ecrire ses m ´ethodes.

(4)

Modularit ´e

Coh ´esion:

chaque m ´ethode accomplie une t ˆache reli ´ee `a une seule notion Couplage:

chaque m ´ethode effectue sa t ˆache de fac¸on ind ´ependante du reste du programme

(5)

Exemple de coh ´esion: code original

public static void circonferenceCercle() {

// Lecture du rayon

System.out.print("Entrer le rayon du cercle: ");

double rayon = Keyboard.readDouble();

while (Keyboard.error() || rayon < 0) {

System.err.println("Mauvaise valeur de rayon.");

System.out.print("Entrer le rayon du cercle: ");

rayon = Keyboard.readDouble();

}

// Calcul de la circonf´erence

double circonference = 2 * Math.PI * rayon;

// Affichage de la circonf´erence

System.out.println("La circonf´erence est " + circonference);

}

(6)

Exemple de coh ´esion: probl `emes

Analyse:

lire d’abord le rayon au clavier, le valider, calculer la circonf ´erence, l’afficher

Probl `emes de coh ´esion

trois t ˆaches: lecture, calcul et affichage.

effort un peu trop grand pour comprendre

r ´ep ´etition du code

r ´eutilisation, maintenabilit ´e: si le rayon n’est pas lu au clavier mais il

(7)

Exemple de coh ´esion: fractionnement 1

Fractionnement en m ´ethodes plus coh ´esives

// Lit le rayon (positif) d’un cercle au clavier.

public static double lireRayon() {

System.out.print("Entrer le rayon du cercle: ");

double rayon = Keyboard.readDouble();

while (Keyboard.error() || rayon < 0) {

System.err.println("Mauvaise valeur de rayon.");

System.out.print("Entrer le rayon du cercle: ");

rayon = Keyboard.readDouble();

}

return rayon;

}

(8)

Exemple de coh ´esion: fractionnement 2

// Calcule la circonf´erence d’un cercle de rayon donn´e.

public static double circonferenceCercle(double rayon) {

return 2 * Math.PI * rayon;

}

// Affiche la circonf´erence d’un cercle.

public static void afficheCirconference(

double circonference) {

System.out.println("La circonf´erence est "

+ circonference);

}

(9)

Exemple de coh ´esion: nouvel appel

Utilisation (de fac¸on minimaliste)

Cercle.afficheCirconference(

Cercle.circonferenceCercle(Cercle.lireRayon()));

M ´ethode sp ´ecialis ´ee

public static void circonferenceCercleInteractif() {

Cercle.afficheCirconference(

Cercle.circonferenceCercle(Cercle.lireRayon()));

}

Renommage

(10)

Encore plus de coh ´esion

lireRayon

n’est pas assez coh ´esive Effectue trois t ˆaches:

lire un nombre avec sollicitation

validation 1: le nombre est bien tap ´e

validation 2: le nombre est positif R ´eutilisation, maintenabilit ´e:

si on voulait lire seulement avec sollicitation

si on voulait lire autre chose qu’un rayon

(11)

Encore plus de coh ´esion: sollicitation

// Lit un nombre r´eel au clavier avec un message // de sollicitation.

public static double lectureReelSollicitee(String msg) {

System.out.print(msg);

return Keyboard.readDouble();

}

(12)

Encore plus de coh ´esion: validation

// Lit un nombre r´eel au clavier avec sollicitation.

// La lecture est recommenc´ee tant qu’un nombre r´eel // n’est pas tap´e.

public static double lectureReelValidee(String msg) {

double valeur = lectureReelSollicitee(msg);

while (Keyboard.error()) {

System.err.println("Veuillez entrer un nombre r´eel.");

valeur = lectureReelSollicitee(msg);

}

return valeur;

}

(13)

Encore plus de coh ´esion: positif

// Lit un r´eel positif au clavier avec sollicitation.

// La lecture est recommenc´ee tant qu’un nombre r´eel // positif n’est pas tap´e.

public static double lectureReelPositif(String msg) {

double valeur = lectureReelValidee(msg);

while (valeur < 0) {

System.err.println("Entrer un nombre r´eel positif!");

valeur = lectureReelValidee(msg);

}

return valeur;

}

Exercice: lire un nombre r ´eel dans un intervalle quelconque

(14)

Encore plus de coh ´esion: appel

Utilisation

double rayon =

Cercle.lectureReelPositif(

"Entrez le rayon du cercle: ");

m ´ethode sp ´ecialis ´ee:

public static double lireRayon() {

return Cercle.lectureReelPositif(

"Entrez le rayon du cercle: ");

}

. . .

double rayon = lireRayon();

(15)

Coh ´esion

Avantages de la coh ´esion

R ´eutilisation plus facile

M ´ethodes complexes moins lourdes

Compr ´ehension: l’unicit ´e des t ˆaches des m ´ethodes

M ´ethodes avec t ˆache simple (unique) plus faciles `a d ´eboguer

(16)

Exemple de couplage

Afficher un triangle

rectangle isoc `ele

l’angle droit en haut

• i

e ligne est remplie de la

i

e lettre de l’alphabet en minuscule Solution mal programm ´ee

avec des variables globales (statiques de classe)

incompr ´ehensible `a cause du couplage

(17)

Exemple de couplage: code original 1

public class Triangle {

// Colonne courante, ligne courante et nombre total de lignes.

public static int colonne, ligne, total;

// Affiche un triangle de nbLignes lignes.

public static void afficheTriangle(int nbLignes) {

total = nbLignes;

for (ligne = 0; ligne < total; ++ligne) { colonne = 0;

afficheEspaces();

afficheLettres();

System.out.println();

} }

(18)

Exemple de couplage: code original 2

// Affiche les espaces au d´ebut de la ligne courante.

public static void afficheEspaces() {

while (colonne < ligne) { System.out.print(’ ’);

++colonne;

} }

// Affiche les ´etoiles de la ligne courante.

public static void afficheLettres() {

while (colonne < total) {

System.out.print((char)(’a’ + ligne));

++colonne;

(19)

Exemple de couplage: analyse

Utilisation:

Triangle.afficheTriangle(10);

O `u est le couplage?

• afficheEspaces

et

afficheLettres

d ´ependent des variables globales

colonne

,

ligne

et

total

• afficheEspaces

d ´epend d’

afficheTriangle

• afficheLettres

d ´epend d’

afficheEspaces

et d’

afficheTriangle

(20)

Exemple de couplage: probl `emes

ces m ´ethodes ne sont pas r ´eutilisables (ou presque)

compr ´ehension: pour comprendre leur fonctionnement, il faut en plus comprendre le r ˆoles des variables globales

maintenabilit ´e: le changement d’une m ´ethode ou variable affectera le comportement d’autres m ´ethodes

(21)

Exemple de couplage: exemples

Mal-utiliser (abuser) des m ´ethodes: LA MAGIE!

afficher une suite de

n

d’espaces

Triangle.colonne = 0;

Triangle.ligne = n;

Triangle.afficheEspaces();

afficher une suite de

n

lettres

Triangle.colonne = 0;

Triangle.ligne = choixDeLaLettre;

Triangle.total = n;

Triangle.afficheLettres();

(22)

Exemple de couplage

Effets de bord

en changeant une variable, le comportement d’une m ´ethode ult ´erieure change (sans changer ses param `etres)

en appelant une m ´ethode une variable change Compr ´ehensibilit ´e

il faut lire tout le programme afin de comprendre l’effet de l’invocation d’une m ´ethode

(23)

Exemple de couplage

R ´e ´ecrire

afficheEspaces

pour enlever son couplage

public static void afficheEspaces(int combien) {

for (int i = 0; i < combien; ++i) System.out.print(’ ’);

}

R ´e ´ecrire

afficheLettres

pour enlever son couplage

afficher

n

espaces est un sous-probl `eme d’afficher

n

fois un m ˆeme caract `ere quelconque

(24)

Exemple de couplage

G ´en ´eraliser

afficheEspaces → repeteCaracteres

public static void repeteCaracteres(char c, int combien) {

for (int i = 0; i < combien; ++i) System.out.print(c);

}

afficher

n

fois la

i

e lettre:

Triangle.repeteCaracteres((char)(’a’ + i), n);

afficher

n

espaces:

Triangle.repeteCaracteres(’ ’, n);

(25)

Exemple de couplage

R ´e ´ecrire

afficheTriangle

pour enlever son couplage:

public static void afficheTriangle(int nbLignes) {

for (int ligne = 0; ligne < nbLignes; ++ligne) { repeteCaracteres(’ ’, ligne);

repeteCaracteres((char)(’a’ + ligne), nbLignes - ligne);

System.out.println();

}

}

(26)

Avantages des m ´ethodes d ´ecoupl ´ees

les variables globales ont disparues

il n’y a plus de d ´ependance entre m ´ethodes

aucun danger d’effet de bord

m ´ethodes r ´eutilisables

(27)

D ´esavantages du couplage

Effets de bord

R ´eutilisation difficile

D ´etection/correction d’erreurs plus difficile

Compr ´ehension des m ´ethodes plus difficiles

In ´el ´egant: alourdit souvent l’ ´ecriture du code

(28)

Directives

Ecrire des´ m ´ethodes ind ´ependantes

Eviter´ autant que possible les variables globales (statiques de classe) Toute information devrait ˆetre communiqu ´ee `a une m ´ethode par

l’interm ´ediaire de param `etres

Exception: les m ´ethodes qui font des lectures sur des p ´eriph ´eriques externes (le clavier, l’ ´ecran)

(29)

Variables globales

A stocker une information` g ´en ´erale et commune dans tout le programme

Exemples:

System.out

,

System.err

,

System.in

A d ´efinir des` constantes g ´en ´erales

Exemples:

Math.PI

,

Integer.MAX VALUE

(30)

Modularit ´e des classes

La notion de modularit ´e ne s’applique pas qu’aux m ´ethodes

Une classe devrait aussi ˆetre modulaire: ˆetre coh ´esive et avec peu de couplage:

une classe devrait ˆetre reli ´ee `a une seule notion

chaque classe devrait ˆetre ind ´ependante

(31)

Exemple de classes modulaires

public class Cercle {

public static double lectureReelSollicitee(String msg);

public static double lectureReelValidee(String msg);

public static double lectureReelPositif(String msg);

public static double lireRayon();

public static double circonferenceCercle(double rayon);

public static void afficheCirconference(double circonference);

}

(32)

Exemple de classes modulaires

public class Cercle {

public static double lectureReelSollicitee(String msg);

public static double lectureReelValidee(String msg);

public static double lectureReelPositif(String msg);

public static double lireRayon();

public static double circonferenceCercle(double rayon);

public static void afficheCirconference(double circonference);

}

les trois m ´ethodes de lecture n’ont rien `a voir avec la notion de cercle

(33)

Exemple de classes modulaires

On se cr ´ee une classe par “module”

public class Cercle // Classe pour la notion de cercle {

public static double lireRayon();

public static double circonferenceCercle(double rayon);

public static void afficheCirconference(double circonference);

}

public class Lecture // Classe pour la notion de lecture {

public static double lectureReelSollicitee(String msg);

public static double lectureReelValidee(String msg);

public static double lectureReelPositif(String msg);

}

(34)

Exemple de classes modulaires

Cercle.lireRayon

:

public static double lireRayon() {

return Lecture.lectureReelPositif(

"Entrez le rayon du cercle: ");

}

Noms redondants:

• Cercle.circonferenceCercle

→ Cercle.circonference

• Triangle.afficheTriangle →

(35)

S ´eparation en fichier

Chaque classe dans un fichier propre `a elle

Rappel: chaque fichier doit porter le m ˆeme nom que la classe plus l’extension

.java

Un fichier ne peut contenir qu’une classe publique

CLASSPATH

: une variable d’environnement qui contient une suite de r ´epertoires o `u le compilateur (et la commande

java

) cherche la d ´efinition des classes

Chaque fichier doit ˆetre compil ´e s ´epar ´ement

(36)

Exemple

Avec les deux classes

Lecture

et

Cercle

, on aurait deux fichiers:

• Lecture.java

pour la classe

Lecture

• Cercle.java

pour la classe

Cercle

Chacun est compil ´e s ´epar ´ement:

• javac Lecture.java

• javac Cercle.java

(37)

Tester une m ´ethode

Pour tester les m ´ethodes, ´ecrire une classe `a part qui les appelle public class TestTriangle

{

public static void main(String[] arg) {

Triangle.afficheTriangle(Integer.parseInt(arg[0]));

} }

Pourquoi?

(38)

Tester une m ´ethode

Pour tester les m ´ethodes, ´ecrire une classe `a part qui les appelle public class TestTriangle

{

public static void main(String[] arg) {

Triangle.afficheTriangle(Integer.parseInt(arg[0]));

} }

Pourquoi?

´eviter les modifications aux classes m ˆemes

travail d’ ´equipe

(39)

Construction de tests simples

Sc ´enario

MaMethode

: la m ´ethode `a tester

conversion i (String arg)

: conversion vers un type d ´esir ´e pour le

i

e param `etre de la m ´ethode

MaMethode

Tester une m ´ethode d’affichage ou interactive public class TestMaMethode

{

public static void main(String[] arg) {

MaMethode(conversion0(arg[0]),conversion1(arg[1]),...);

} }

(40)

Construction de tests simples

Tester le retour d’une m ´ethode public class TestMaMethode {

public static void main(String[] arg) {

System.out.println(MaMethode(conversion0(arg[ 0]),

conversion1(arg[ 1]), ... ));

} }

Compilation:

javac TestMaMethode.java

Ex ´ecution:

java TestMaMethode arg0 arg1 ...

(41)

Tester lectureReelValidee

pas de conversion, le param `etre est de type

String

public class TestLectureReelValidee {

public static void main(String[] arg) {

System.out.println(

Lecture.lectureReelValidee(arg[0]));

} }

compilation:

javac TestLectureReelValidee.java

ex ´ecution: java TestLectureReelValidee "Entrez un nombre reel: "

(42)

Tester Cercle.circonference

conversion,

String → double

public class TestCirconference {

public static void main(String[] arg) {

System.out.println(Cercle.circonference(

Double.parseDouble(arg[0])));

} }

compilation:

javac TestCirconference.java

(43)

Tests plus complexes

Boucles pour tester la m ´ethode syst ´ematiquement pour plusieurs valeurs des param `etres

Pour les m ´ethodes qui utilisent des entr ´ees et des sorties, construire des fichiers d’entr ´ees et proc ´eder par redirection

Références

Documents relatifs

– valeurDeConst doit ˆetre ´evaluable pendant la compilation – valeur litt ´erale, une autre constante, une expression contenant.

Lorsque quelqu’un pourrait ne pas comprendre le sens d’une instruction. – doit d ´ecrire le sens, pas l’instruction – ne pas commenter

si elle est ´egale `a n’importe quelle &lt;constante&gt; , l’ex ´ecution se poursuit `a partir de l’ ´etiquette &lt;constant&gt;:. sinon, l’ex ´ecution se poursuit `a partir

Objectif: r ´ep ´eter un groupe d’instructions tant qu’une condition est satisfaite, mais au moins une

• en principe, elles peuvent ˆetre red ´eclar ´ees dans les m ´ethodes, mais c’est fortement d ´econseill ´e. • normalement, elles sont final es, les variables

• les valeurs sorties de ces op ´erateurs sont utilis ´ees rarement Deux types d’op ´erandes: r ´ef ´erence et valeur. IFT-1015 Stefan

Une classe repr ´esente un ensemble d’objets qui partagent les m ˆeme propri ´et ´es, r ´epondent aux m ˆeme requ ˆetes et commandes.. Chaque objet est une instance

En Java, la valeur initiale de chaque cellule est 0 pour les nombres, le caract `ere 0 pour les caract `eres, ou null pour les objets (y compris les chaˆınes de caract