Arnaud Labourel
26 novembre 2021
Il est possible de définir une classe à l’intérieur d’une autre (classe imbriquée ou nested class) :
public class LinkedList {
public static class Node {
private String data; private Node next;
public Node(String data, Node next) {
this.data = data; this.next = next;
}
}
}
Il est possible d’instancier la classe interne sans qu’une instance de LinkedList
existe car elle est statique :
Une classe non-imbriquée publique (public
) doit être dans un fichier portant son nom.
Fichier LinkedList.java
⇒ erreur à la compilation :
Une classe imbriquée peut être publique et accessible depuis l’extérieur.
Il est également possible de la rendre privée à la classe LinkedList
:
public class LinkedList {
private static class Node {
private String data;
private /*LinkedList.*/Node next;
public Node(String data, Node next) {
this.data = data;
this.next = next;
}
}
}
Dans ce cas, seules les méthodes de LinkedList
pourront l’utiliser. Notez que des méthodes statiques définies dans LinkedList
peuvent également utiliser cette classe interne du fait qu’elle soit statique.
Exemple d’implémentation de méthodes dans la classe LinkedList
:
Exemple d’utilisation de la classe précédente :
Cet exemple produit la sortie suivante :
[c][b][a]
Une classe imbriquée statique ne peut accéder qu’aux attributs et méthodes statiques de la classe qui la contient :
En revanche, si la classe interne n’est pas statique, elle peut accéder aux champs de classe qui la contient :
Java insère dans l’instance de Node
une référence vers l’instance de LinkedList
qui a permis de la créer :
Il est possible d’utiliser la méthode isFirst
dans LinkedList
:
Exemple d’utilisation de la classe précédente :
Cet exemple produit la sortie suivante :
[c,true][b,false][a,false]
Rechercher et caractériser les fonctions qu’un logiciel devrait avoir pour satisfaire les besoins de son utilisateur.
Hiérarchiser ces fonctions.
Utilisée pour créer mais aussi améliorer un logiciel (ou plus généralement un produit).
Fonction principale : la raison pour laquelle le logiciel est créé. Cette fonction peut être divisée en plusieurs fonctions simples.
Fonction contrainte : conditions que le produit doit vérifier mais qui ne sont pas sa raison d’exister (par exemple la sécurité).
Fonction complémentaire : ce qui facilite l’utilisation du logiciel, l’améliore ou le complète.
Un outil de l’analyse fonctionnelle : lister, décrire et hiérarchiser les fonctions.
Fonction principale :
Fonctions contraintes :
Fonctions complémentaires:
Livrable : produit destiné à la livraison : documentation, code, tests, etc…
Jalon : fin d’une étape ou évènement important.
Le début d’un projet et sa fin sont des jalons. On fixe des jalons intermédiaires pour mesurer l’avancée du projet.
Un jalon peut être un livrable lié à une date.
Développer un logiciel implique de :
Deux types de management pour y parvenir :
Méthode traditionnelle, inspirée par le BTP.
Passage d’une phase à l’autre uniquement quand la précédente est terminée et vérifiée.
Inconvénient : très peu réactif en cas d’erreur ou de modification nécessaire en cours de projet.
Un amélioration du modèle en cascade : limiter le retour aux étapes précédentes.
Standard depuis 1980.
Phase ascendante : renvoie de l’information sur la phase correspondante pour améliorer le logiciel.
Phase descendante : anticipation des attendus des étapes montantes.
Inconvénient : détache complètement la conception de la réalisation.
Objectifs :
Définition par le manifeste Agile (2001).
Exemples :
Théorisé par Kent Beck
Une classe ne doit avoir qu’une responsabilité = raison de changer
Programme ouvert pour l’extension, fermé à la modification
Vous devez pouvoir ajouter une nouvelle fonctionnalité :
interface Shape {
void draw();
}
public class Circle implements Shape {
Point center;
int radius;
public void draw(){ ... }
}
public class Rectangle implements Shape {
Point TopLeft, RightBottom;
public void draw(){ ... }
}
public class GraphicTools {
static void draw(Object[] shapes){
for(Shape s : shapes){
s.draw();
}
}
}
Les sous-types doivent être substituables par leurs types de base.
Si une classe A étend une classe B alors un programme P écrit pour manipuler des instances de type B doit avoir le même comportement s’il manipule des instances de la classe A.
Violation de LSP :
public void test(Rectangle r) {
r.setWidth (2);
}
r.setHeight(3);
if (r.getArea()!=3*2)
System.out.println(”bizarre !”);
Un carré est-il un rectangle ?
Pour les utilisateurs, votre carré a-t-il le même comportement que votre rectangle ?
La réponse : Dans ce cas, NON
## Dependency Inversion Principle (DIP)
### Principe :
Les modules d’un programme doivent être indépendants Les modules doivent dépendre d’abstractions Signification et objectifs :