Arnaud Labourel
22 septembre 2021
“Mal nommer un objet, c’est ajouter au malheur de ce monde”
La L3 info : MIAGE ne dépend pas de la même UFR que la L2 info : MI, elle dépend de la FEG et non de la FS. Pour faire vos IA et IP, vous devez donc contacter la scol de Forbin et non celle de SCH.
i
, j
, …a1
, a2
, a3
, …rec
, res
, …temporary
, result
, …accountList
doit être une List
(et pas un array
ou un autre type)persons
et non person
.genymdhms
, …Le Java et la quasi-totalité des langages de programmation utilise l’anglais (dans les mot-clés et les librairies standards).
⇒ On doit programmer en anglais pour avoir la cohérence du code
Utiliser l’anglais permet aussi d’augmenter le nombre de personnes pouvant lire le code et d’avoir de nombreux exemples existants pour s’inspirer.
Un nom composé de plusieurs mots n’utilise ni espace ni ponctuation, et sépare les mots en mettant en capitale la première lettre de chaque mot.
Exemples: getElementsByTagName
, ListArray
, …
Méthodes modifiant l’état de l’objet
⇒ groupe verbal à l’infinitif.
boolean add(E element)
E set(int index, E element)
boolean removeAll(Collection<?> c)
Méthodes renvoyant une partie de l’état de l’objet ⇒ groupe nominal ou getter.
int size()
List<E> subList(int fromIndex, int toIndex)
int hashcode()
ListIterator<E> listIterator()
E get(int index)
Color getBackground()
float getOpacity()
Méthodes testant un prédicat sur l’objet ⇒ groupe verbal au présent.
boolean isEmpty()
boolean contains(Object o)
boolean equals(Object o)
Exemples :
String toString()
Object[] toArray()
Les règles ne sont pas absolues mais juste des conventions qui peuvent avoir des exceptions.
En général le plus simple est de s’inspirer de l’existant : par exemple la JDK et de bien réfléchir lorsqu’on souhaite déroger aux règles.
class User {
private boolean authenticated;
private String password;
public boolean checkPassword(String password) {
if (password.equals(this.password)) {
authenticated = true;
return true;
}
return false;
}
}
La méthode authentifie l’utilisateur alors qu’elle ne devrait que vérifier la validité du mot de passe d’après son nom.
Une fonction ne doit faire qu’une seule chose.
Pour cela, elle ne doit réaliser que des étapes de même niveau d’abstraction.
On décompose la fonction :
Pour faire la cuisine je dois (premier niveau d’abstraction) :
Pour choisir une recette, je dois (deuxième niveau d’abstraction):
void cook(){
// On choisit la recette
Food wantToEat = thinkAboutFood();
Recipe recipe = lookOnMarmiton(wantToEat);
// On réunit les ingrédients
openFridge();
for(Ingredient ingredient :
recipe.getFreshIngredients()){
takeInFrige(ingredient);
}
closeFridge();
openCupboard();
...
// On suit la recette
...
}
Un programme est “bien conçu” s’il permet de :
Un code non testé n’a aucune valeur.
Tout code doit être testé
Tester une unité de code : classe, méthodes, …
Vérifier un comportement :
JUnit
avec AssertJ
@Test
(à mettre avant la déclaration de la méthode)AssertionError
en cas de test échouéles tests sont séparés du code de production : répertoire main
pour le code de production et répertoire test
pour le code de tests.
⇒ nécessaire de séparer les test du code de production car :
AssertJ
(1/2)assertThat(condition).isTrue()
: vérifie que condition
est vraie.
assertThat(condition).isFalse()
: vérifie que condition
est faux.
assertThat(actual).isEqualTo(expected)
: vérifie que expected
est égal à actual
égal : equals
pour les objets et ==
pour les types primitifs.
assertThat(actual).isCloseTo(expected, within(delta))
: vérifie que |expected − actual| ≤ delta
assertThat(object).isNull()
: vérifie que la référence est null
AssertJ
(2/2)assertThat(object).isNotNull()
: vérifie que la référence n’est pas null
assertThat(actual).isSameAs(expected)
: vérifie que les deux objets sont les mêmes (même référence).assertThat(list).containsExactly(e1, e2, e3)
: vérifie que la liste list
contient uniquement les éléments e1
, e2
et e3
dans cet ordre.assertThat(list1).containsExactlyElementsOf(list2)
: vérifie que les deux listes list1
et list2
contiennent les mêmes éléments dans le même ordre.fail(message)
: échoue toujours en affichant messageIl est possible de provoquer l’affichage d’un message
lors d’un test faux en appelant as(message)
sur le retour d’un assertThat
.
RationalNumber
public class RationalNumber {
public final int numerator;
public final int denominator;
public RationalNumber(int numerator, int denominator) {
int gcd = gcd(numerator, denominator);
this.numerator = numerator / gcd;
this.denominator = denominator / gcd;
}
public RationalNumber add(RationalNumber val) {
int numerator = (this.numerator * val.denominator) + (this.denominator * val.numerator);
int denominator = this.denominator * val.denominator;
return new RationalNumber(numerator, denominator);
}
...
}
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.*;
public class RationalNumberTest {
@Test
void testAdd(){
RationalNumber one = new RationalNumber(1, 1);
RationalNumber onePlusOne = one.add(one);
assertThat(onePlusOne.numerator)
.as("Numerator of one plus one is two.")
.isEqualTo(2);
assertThat(onePlusOne.denominator)
.as("Denominator of one plus one is one.")
.isEqualTo(1);
}
}
Emails
public class Emails {
private String text;
public Emails(String text) { this.text = text; }
public List<String> userNames() {
int pos = 0;
List<String> users = new ArrayList<String>();
for(;;) {
int atIndex = text.indexOf('@', pos);
if (atIndex == -1) break;
String userName = userName(atIndex);
if (userName.length() > 0) users.add(userName);
pos = atIndex + 1;
}
return users;
}
Emails
@Test
public void testUsersChars() {
Emails emails =
new Emails("fo f.ast@cs.edu bar&a.2.c@ms.com ");
assertThat(emails.getUserNames())
.containsExactly("f.ast", "a.2.c");
}
@Test
public void testUsersChars() {
Emails emails =
new Emails("fo f.ast@cs.edu bar&a.2.c@ms.com ");
assertThat(emails.getUserNames())
.containsExactly("f.ast", "a.2.c");
}
@Test
public void testUsersHard() {
Emails emails = new Emails("x y@cs 3@ @z@");
assertThat(emails.getUserNames())
.isNotEmpty();
.containsExactly("y", "3", "z");
emails = new Emails("no emails here!");
assertThat(emails.getUserNames()).isEmpty();
emails = new Emails("@@@");
assertThat(emails.getUserNames()).isEmpty();
emails = new Emails("");
assertThat(emails.getUserNames()).isEmpty();
}
}
clone
ou init
)pull
)add
)commit
)push
)git clone adresse_projet
⇒ Clone un projet en local depuis un serveur
git add nom_de_fichier
⇒ Ajoute un fichier à la prochaine mise à jour.
git commit -m"commentaire"
⇒ Fait une mise à jour en local
git pull
⇒ Récupère les mises à jour du serveur en local
git push
⇒ Pousse les mises à jour locales sur le serveur
clone
, add
, commit
, push
, pull
, …
Comment rendre le nommage des méthodes facile ?
En écrivant des méthodes courtes
De préférence une dizaine de ligne maximum.
Comment écrire des méthodes courtes
En extrayant le plus possible les partie du code d’une méthode à d’autres méthodes.
Conseils