SlideShare une entreprise Scribd logo
1  sur  82
Télécharger pour lire hors ligne
Qualité logicielle
Cyril Gandon
Introduction
 Vous savez coder : lire et écrire un fichier, afficher un résultat à l’écran,
lancer plusieurs Threads, manipuler des listes, etc.
 Etes vous attentifs à la qualité de votre code ?
 Un logiciel ne se résume pas à ses fonctionnalités
 Son potentiel de croissance est au moins aussi important que ses
fonctionnalités

 Un code de qualité est tourné vers le futur : maintenable, modulable
Objectifs
 Etre capable de reconnaitre le manque de qualité d’un code
 Etre capable d’appliquer les méthodes de refactoring pour augmenter la
qualité
 Comprendre les enjeux de la qualité logicielle
 Connaitre les outils applicables pour écrire un code de qualité
Sommaire
1.

Mesure de la qualité

2.

Le Refactoring

3.

Les principes S.O.L.I.D.

4.

Initiation à la programmation fonctionnelle

5.

Analyse statique

6.

Programmation par contrat
1. Mesure de la qualité
La théorie : Norme ISO 9126 Software
engineering — Product quality


Functionality : The existence of a set of functions and their specified properties. The functions are those that satisfy stated or
implied needs.




Reliability : The capability of software to maintain its level of performance under stated conditions for a stated period of
time.




Time Behaviour, Resource Utilization, Efficiency Compliance

Maintainability : The effort needed to make specified modifications.




Understandability, Learnability, Operability, Attractiveness, Usability Compliance

Efficiency : The relationship between the level of performance of the software and the amount of resources used, under
stated conditions.




Maturity, Fault Tolerance, Recoverability, Reliability Compliance

Usability : The effort needed for use, and on the individual assessment of such use, by a stated or implied set of users.




Suitability, Accuracy, Interoperability, Security, Functionality Compliance

Analyzability, Changeability, Stability, Testability, Maintainability Compliance

Portability : The ability of software to be transferred from one environment to another.


Adaptability, Installability, Co-Existence, Replaceability, Portability Compliance



Source : http://en.wikipedia.org/wiki/ISO/IEC_9126
En pratique
 Fonctionnel
 Maintenable
 KISS : Keep It Simple Stupid
 YAGNI : You Ain’t Gonna Need It
 DRY : Don’t Repeat Yourself

 Performant (Théorie de la complexité)
 Robuste (Parallélisable, Portable)
 Testable (Via les tests unitaires)
Fonctionnel
 Développer les fonctionnalités demandées
Maintenable
 Simplicité, simplicité, simplicité
 Lisibilité

 Pas de code spaghetti
 Ne soyez pas un « Astronaute Architecte » = Ne surdésigner pas le model
 Ne vous répétez pas, n’écrivez jamais deux fois le même code
Performant
 Soyez conscient de la complexité de votre algorithme
 O(1) > O(log n) > O(n) > O(n log n) > O(n²)
Robuste
 Comment réagi votre logiciel « au bord »
 Et si le réseau tombe ?

 Et si l’utilisateur rentre de mauvaises données ?
 Et si les données reçues sont dans un mauvais format ?
 Fail fast => Valider toujours et échouer rapidement
Testable
 La couverture des tests unitaires doit approcher les 100%
 Réduit les dépendances

 Diminue les régressions
2. Le Refactoring
Le refactoring, c’est quoi ?
 Définition : la modification du code d’un logiciel dans le but de le rendre
plus simple à comprendre et à modifier, sans changer son comportement
observable
 Simplifier le code
 Accroitre sa lisibilité

 Un code est écrit 1 fois et lu 10 fois
 80% du temps est passé à la maintenance, donc la relecture

 Gagner en robustesse
 Du temps investi aujourd’hui pour une maintenance plus simple demain
 Ne modifie pas les fonctionnalités existantes
(Re)Factorisation d’une identité
remarquable
a² + 2ab + b²

(a + b)²

 a = 2, b = 4

 a = 2, b = 4

 2² + 2 * 2 * 4 + 4² = ?

 (2 + 4)² = 36
Références
 http://refactoring.com

 http://sourcemaking.com/refactoring
Quelques principes
1. Renommage
2. Découper les fonctions

3. Réduire les paramètres
4. Réduire le scope des variables
5. Rendre les objets immutables
6. Eviter les négations et supprimer les doubles négation
7. Introduire des variables temporaires pour des expressions complexes
8. Ne pas utiliser la même variable pour autres chose
9. Séparer les niveaux (layers) d’abstraction
10. Loi de Demeter
1. Renommage
 Un bon nom doit être dicible par téléphone
 Notation PascalCase pour les classes et méthodes, camelCase pour les
variables (en C#)
 Doit décrire précisément l’action ou l’état représenté
 Suivre les conventions de nommages de son langage (Java != C# != PHP),
ou de son entreprise si elles existent
The name of a method does not reveal its purpose.
Change the name of the method.
2. Découper les fonctions
 Diviser pour régner, mieux vaut plusieurs petites fonctions qu’une seule
grosse
 Une fonction ne devrait jamais dépasser quelques dizaines de lignes

void printOwing()
{
printBanner(); //print details
System.out.println ("name: " + _name);
System.out.println ("amount " +
getOutstanding());
}

void printOwing()
{
printBanner();
printDetails(getOutstanding());
}
void printDetails (double outstanding)
{
System.out.println ("name: " + _name);
System.out.println ("amount " + outstanding);
}
3. Réduire le scope des variables
 Une variable doit être déclarer au plus proche de son utilisation, dans le
scope (contexte) le plus faible
 Permet de suivre l’algorithme plus facilement. Le cerveau ne peut pas
retenir plus de 6-7 variables
 Implique d’éviter au maximum les variables static qui ont un scope global à
toute l’application
3. Réduire le scope des variables

public int Foo(int j)
{
int i = 2;
int a;
if (j > 3)
{
a = i * i;
}
else
{
a = 0;
}
return a;
}

Scope de i

public int Foo(int j)
{
int a;
if (j > 3)
{
int i = 2;
a = i * i;
}
else
{
a = 0;
}
return a;
}

Scope de i
4. Réduire le nombre de paramètres
 Le nombre de paramètres d’une méthode ne devrait jamais dépasser 3 ou
4
 Grouper ensemble les paramètres qui ont un sens commun

You have a group of parameters that naturally go together.
Replace them with an object.
5. Rendre les objets immutables
 Un objet sans setters (immutable) est plus simple à manipuler et plus
sécurisant (CF la programmation fonctionnelle)
 Peut être passer à des tiers sans effet de bords

 Laisser les mutants à la science fiction, pas à la science informatique
5. Rendre les objets immutables
public class MyPoint
{
private double _x;

public class MyPoint
{
private readonly double _x;

public double X
{
get { return _x; }
set { _x = value; }
}
private double _y;

public double X
{
get { return _x; }
}
private readonly double _y;
public double Y
{
get { return _y; }
}

public double Y
{
get { return _y; }
set { _y = value; }
}
public MyPoint(double x, double y)
{
this.X = x;
this.Y = y;
}

}

public MyPoint(double x, double y)
{
this._x = x;
this._y = y;
}
}
6. Eviter les négations et les doubles
négation
 La lecture est toujours plus simple dans le sens positif que dans le sens
négatif
double foo;
if(this.HasValue == false)
foo = 0;
else
foo = 1;

double foo;
if(this.HaveValue)
foo = 1;
else
foo = 0;

if(!this.NotFound())

if(this.Found())
7. Introduire des variables temporaires
pour des expressions complexes
 Condenser un trop plein d’informations dans une variable nommée
if ( (platform.toUpperCase().indexOf("MAC") > -1) &&
(browser.toUpperCase().indexOf("IE") > -1) &&
wasInitialized() && resize > 0
)
{
// do something
}

final boolean isMacOs = platform.toUpperCase().indexOf("MAC") > -1;
final boolean isIEBrowser = browser.toUpperCase().indexOf("IE") > -1;
final boolean wasResized = resize > 0;
if (isMacOs && isIEBrowser && wasInitialized() && wasResized)
{
// do something
}
8. Ne pas utiliser la même variable pour
2 concepts différents
 Garder en tête la signification d’une variable est difficile, encore plus si elle
change en cours de route
 Mieux vaut créer une nouvelle variable
 L’idéal est qu’une variable doit être assignée une seule fois (paradigme de
la programmation fonctionnelle)

double temp = 2 * (_height + _width);
System.out.println (temp);
temp = _height * _width;
System.out.println (temp);

final double perimeter = 2 * (_height + _width);
System.out.println (perimeter);
final double area = _height * _width;
System.out.println (area);
9. Séparer les niveaux (layers)
d’abstraction
 Identifier et séparer les différentes couches de l’application
 Généralement se sont les suivantes
 Couche métier (algorithme, logique = BML, Buisness Model Layer)
 Couche de présentation (Vue/View)
 Couche d’accès aux données (DAL, Data Access Layer)

 Voir le Pattern MVC pour un tel découpage (Model Vue Controller)
10. Loi de Demeter
 L’antipattern : Feature Envy
 var c = a.GetB().GetC();
 Augmente le couplage

 Définition : Ne parlez qu’à vos amis directs
 Vous pouvez jouer avec vous même
 Vous pouvez jouer avec vos jouets

 Vous pouvez jouer avec les jouets que l’on vous donne
 Vous pouvez jouer avec les jouets que vous avez fabriqués
10. Loi de Demeter
 Définition : soit la méthode M de l’objet O. La méthode M à la droit
d’invoquer les méthodes de :
 O lui-même
 Des attributs / propriétés de O
 Des paramètres de M
 Des objets instanciés dans M

var employees = someObject.GetEmployeeList();
employees.AddElementWithKey(employee.GetKey(), employee);

someObject.AddToEmployees(employee);
Conclusion & Problématique
 Le refactoring n’ajoute pas de fonctionnalité, ne corrige pas de bugs
 Comment vendre du temps d’improductivité à votre entreprise ?

Source : http://dilbert.com/strips/comic/2007-11-26/
Conclusion
 Le refactoring est un investissement toujours payant, à vous de savoir le
vendre
 Le refactoring est une partie importante des méthodes agiles => Coder
vite, livrer vite, refactoriser, boucler
 Fonctionne de pair avec les tests unitaires
3. Les principes S.O.L.I.D.
C’est quoi SOLID ?
 Les pratiques SOLID permettent d’avoir des outils pour construire des
logiciels de qualité
 Introduites par Robert C. Martin en 2000 dans son article « Design Principles
and Design Patterns »
 SOLID est un acronyme de cinq lettres représentant pour chaque lettre 1
principe à respecter
S.O.L.I.D.
 Single responsibility principle
 Open/closed principle

 Liskov substitution principle
 Interface segregation principle
 Dependency inversion principle
Single responsibility principle
 Un objet doit avoir une seule responsabilité
 Un objet doit avoir une seule raison de changer
Mauvais exemple
 Lit un fichier
 Parse et valide les données

public class Fruit
{
public int Id { get; set; }
public string Name { get; set; }
public static IEnumerable<Fruit> FruitsFromFile(string path)
{
// 0;Apple
// 1;Orange
// 2;Banana
using (var reader = new StreamReader(path))
{
string line;
while ((line = reader.ReadLine()) != null)
{
var words = line.Split(';');
int id = Convert.ToInt32(words[0]);
string name = words[1];
yield return new Fruit() { Id = id, Name = name };
}
}
}

 Non testable unitairement

}
Séparer les responsabilités
// Représente un fruit dans un fichier
public class FruitFile
{
public string Id { get; set; }
public string Name { get; set; }
public static IEnumerable<FruitFile> FruitsFromFile(string
path)
{
using (var reader = new StreamReader(path))
{
string line;
while ((line = reader.ReadLine()) != null)
{
var words = line.Split(';');
yield return new FruitFile()
{ Id = words[0], Name = words[1] };
}
}
}
}

public class Fruit
{
public int Id { get; set; }
public string Name { get; set; }
// Valide les données d'une ligne fruit
public static Fruit Build(FruitFile fruitFile)
{
int id = Convert.ToInt32(fruitFile.Id);
string name = fruitFile.Name;
return new Fruit() { Id = id, Name = name };
}
public static IEnumerable<Fruit> FromFile(string path)
{
return FruitFile.FruitsFromFile(path)
.Select(fruitFile => Build(fruitFile));
}
}

 La validation des données devient testable unitairement
Open/closed principle
 Un objet doit être ouvert à l’extension mais fermer à la modification
Open/closed principle
 Ouvert à l’extension = Possibilité de rajouter des fonctionnalités
 Fermé à la modification = Ajout des fonctionnalités sans changer le code
existant
 Mécanisme : Héritage, Polymorphisme, Interface (Abstraction)
Mauvais exemple
public class Rectangle
{
public double Width { get; set; }
public double Height { get; set; }
public double Area { get { return this.Width * this.Height;
} }
}
public class Circle
{
public PointF Center { get; set; }
public double Radius { get; set; }
public double Area
{
get { return this.Radius * this.Radius * Math.PI; }
}
}

public class Shapes
{
public double AreaOf(List<object> shapes)
{
double total = 0;
foreach (var shape in shapes)
{
if (shape is Rectangle)
{
total += ((Rectangle)shape).Area;
}
else if (shape is Circle)
{
total += ((Circle)shape).Area;
}
}
return total;
}
}

 Obligation de modifier la fonction si on ajoutait un triangle
Ajout d’un niveau d’abstraction
// Abstract the Shape concept
public interface IShape { double Area { get; } }
public class Rectangle : IShape
{
public double Width { get; set; }
public double Height { get; set; }
public double Area { get { return this.Width * this.Height; } }
}
public class Circle : IShape
{
public PointF Center { get; set; }
public double Radius { get; set; }

public class Shapes
{
// Can run with abstract list of shapes
public double AreaOf(IEnumerable<IShape> shapes)
{
double total = 0;
foreach (var shape in shapes)
{
total += shape.Area;
}
return total;
}
}

public double Area
{
get { return this.Radius * this.Radius * Math.PI; }
}
}

 Le code est extensible pour n’importe quel forme
Liskov substitution principle
 Une classe doit pouvoir être remplacée par une instance d'une des ses
sous-classes, sans modifier la validité du programme
Liskov substitution principle
 Une sous classe ne doit pas être plus contraignante que sa super classe
 Ce qui peut rentrer dans la sous classe doit être moins contraignant que ce
qui peut rentrer dans la super classe
 Ce qui peut sortir de la sous classe doit être plus contraignant que ce qui
peut sortir de la super classe
Mauvais exemple
public class Fish { }
public class Duck
{
public virtual void Give(Fish food)
{
Console.WriteLine("Eating the fish");
}

public class RubberDuck : Duck
{
public override void Give(Fish food)
{
throw new InvalidOperationException("Rubber Duck
doesn't need fishes");
}

public virtual int LegCount { get { return 2; } }
}

public override int LegCount { get { return 0; } }
}

 Le canard en plastique ne sait pas manger un poisson, il est plus
contraignant sur ce qui rentre
 Les canards devrait toujours avoir des pattes
Mauvais exemple
public class Test
{
public void Main()
{
var duck = new RubberDuck();
var fish = new Fish();
this.GiveFood(duck, fish);
}
public void GiveFood(Duck duck, Fish fish)
{
// we are expecting that is will never fail
// unless we violate the Liskov Principle
duck.Give(fish);
}
}

 Un canard en plastique n’est pas un canard
 La modélisation est incorrecte, et viole le principe de Liskov
 On ne peut pas supposer un comportement si le principe de Liskov n’est
pas respecté
Interface Segregation Principle
 Il vaut mieux avoir plusieurs interfaces spécifiques plutôt qu'une seule
grande interface
Mauvais exemple
// Big interface, so much work
public interface ICommunicate
{
void Send(object data);
object Receive();
}

public class Printer : ICommunicate
{
public void Send(object data)
{
Console.WriteLine("Printing datas...");
}

// Phone is ok, can communicate both ways
public class Phone : ICommunicate
{
public void Send(object data)
{
Console.WriteLine("Composing
number...");
}

// Printer has to define the Receive method
public object Receive()
{
// But printer can't receive anything
throw new InvalidOperationException("Printer
are not receiving.");
}
}

public object Receive()
{
return "Dring!";
}
}
Bon exemple
// make it two interfaces instead of one
public interface ISender { void Send(object data); }
public interface IReceiver { void Send(object data); }
public class Phone : ISender, IReceiver
{
public void Send(object data)
{
Console.WriteLine("Composing number...");
}

public object Receive()
{
return "Dring!";
}
}
public class Printer : ISender
{
public void Send(object data)
{
Console.WriteLine("Printing datas...");
}
}
Dependency Inversion Principle
 Les modules de haut niveau ne doivent pas dépendre des modules de bas
niveau. Les deux doivent dépendre des abstractions
Mauvais exemple
// Low level module
public class Logger
{
public void Log(string text)
{
Console.WriteLine(text);
}
}
// High level module, depend on low level module
public class DatabaseReader
{
public Logger Logger { get; set; }
public void ReadData()
{
this.Logger.Log("Reading datas...");
}
}
Bon exemple
// Abstraction
public interface ILogger
{
void Log(string text);
}

// Low level modules, depend on abstraction
public class ConsoleLogger : ILogger
{
public void Log(string text)
{
Console.WriteLine(text);
}
}
// Low level modules, depend on abstraction
public class FileLogger : ILogger
{
private readonly string _path;
public FileLogger(string path)
{
this._path = path;
}
public void Log(string text)
{
using (var file = new
StreamWriter(this._path))
{
file.WriteLine(text);
}
}
}

// High level module, depend on abstraction
public class DatabaseReader
{
public ILogger Logger { get; set; }
public void ReadData()
{
this.Logger.Log("Reading datas...");
}
}
Conclusion
 Appliquer ces principes ne garantissent pas un code sans faille, mais au
moins un meilleur code
 Il faut savoir pondérer ces bonnes pratiques lorsque les délais sont courts et
les résultats pressants
 Les définitions des principes sont simples, mais leurs mises en place
complexe sur des problèmes réels
4. Initiation à la
programmation fonctionnelle
Historique
 Programmation procédurale : Fortran, C, Basic…
 A base de fonction qui s’appelle les unes les autres
 Ensemble d’étape à exécuter pour arriver au résultat

 Programmation orientée objet : C++, Java, C#
 Définition d’un ensemble d’objet interagissant entre eux
 Un objet est définit par ses états (variables) et ses comportements (méthodes)

 Grande mode à partir des années 80, adopté en masse par les entreprises dans
les années 90
Historique
 Aujourd’hui : le marché est toujours dominé par la programmation orienté
objet, et les langages procéduraux gardent une bonne place

Source : http://www.tiobe.com
Historique de la programmation
fonctionnelle
 Programmation fonctionnelle : Lisp (1958), puis Scheme (1975), Haskell
(1987), ou récemment F# (2002) et LINQ (2007)
 N’a jamais réussi à pénétrer le marché malgré son ancienneté
 Peu enseigné, peu pratiqué, peu utilisé
A quoi ça sert alors ?
 Simple à écrire, condensé
 Puissant

 Pas d’effet de bords par nature
 Les principes de la programmation fonctionnelle sont applicables à la
programmation orienté objet
 Rend toute fonction parallélisable
 Rend possible la mise en cache de manière automatique
Paradigmes
 Aucun état n’est modifiable, on parle d’Immutabilité
 Un objet est instancié une fois, puis ne peux plus jamais être modifié

 Les fonctions sont Pures, pas d’effet de bords = aucune modification d’état
 Une fonction pure est une fonction qui ne modifie aucun état, et qui retourne
une seule valeur
 La valeur retournée est toujours la même pour les mêmes arguments d’entrée.
Contrexemple : Date date = new Date(); // Impur
Immutabilité
 Sur des objets, l’initialisation passe par le constructeur
public class ImmutablePoint
{
private readonly double _x;
public double X { get { return _x; } }
private readonly double _y;
public double Y { get { return _y; } }
public ImmutablePoint(double x, double y)
{
this._x = x;
this._y = y;
}
}
Immutabilité
 Sur des conteneurs de données, chaque ajout retourne une nouvelle
instance du conteneur

var empty = new ImmutableList<double>();
var onlyTwo = empty.Add(2);
var twoAndThree = onlyTwo.Add(3);
Avantage de l’immutabilité
 Les variables ne pourront jamais être modifié par un code tiers

public void EvilCode(List<int> ints)
{
ints.Clear();
}

var primes = new List<int>() { 2, 3, 5, 7};
EvilCode(primes);
// ergh, primes is empty!
Avantage de l’immutabilité
 La programmation multi thread est simplifiée
 Pas de Lock, Mutex, et autres joyeusetés

 Les accès aux données sont automatiquement en lecture seule
Exemple : un tas immutable

public interface IStack<T> : IEnumerable<T>
{
IStack<T> Push(T value);
IStack<T> Pop();
T Peek();
bool IsEmpty { get; }
}
Exemple : un tas immutable
public sealed class Stack<T> : IStack<T>
{
private sealed class EmptyStack : IStack<T>
{
public bool IsEmpty { get { return true; } }
public T Peek() { throw new Exception("Empty stack"); }
public IStack<T> Push(T value) { return new Stack<T>(value, this); }
public IStack<T> Pop() { throw new Exception("Empty stack"); }
public IEnumerator<T> GetEnumerator() { yield break; }
IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); }
}
private static readonly EmptyStack empty = new EmptyStack();
public static IStack<T> Empty { get { return empty; } }
private readonly T head;
private readonly IStack<T> tail;
private Stack(T head, IStack<T> tail)
{
this.head = head;
this.tail = tail;
}
public bool IsEmpty { get { return false; } }
public T Peek() { return head; }
public IStack<T> Pop() { return tail; }
public IStack<T> Push(T value) { return new Stack<T>(value, this); }
public IEnumerator<T> GetEnumerator()
{
for (IStack<T> stack = this; !stack.IsEmpty; stack = stack.Pop())
yield return stack.Peek();
}
IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); }
}
Exemple : un tas immutable
IStack<int>
IStack<int>
IStack<int>
IStack<int>

s1
s2
s3
s4

=
=
=
=

Stack<int>.Empty;
s1.Push(10);
s2.Push(20);
s2.Push(30); // shares its tail with s3.

Source : http://blogs.msdn.com/b/ericlippert/archive/2007/12/04/immutability-in-c-parttwo-a-simple-immutable-stack.aspx
LINQ : Application au monde réel
 LINQ arrive en 2007 avec le Framework .NET 3.5
 Ensemble de fonctions inspiré de la programmation fonctionnelle qui agit
sur des types IEnumerable (basiquement, des List)
Un peu de LINQ : filtrer les éléments
d’une liste
 Avant

 Après

public List<int> MutableEvens(List<int> ints)
{
var evens = new List<int>();
foreach (var item in ints)
{
if (item % 2 == 0)
{
// mutation of the list
evens.Add(item);
}
}
return evens;
}

public List<int> ImmutableEvens(List<int> ints)
{
return ints.Where(i => i % 2 == 0).ToList();
}

 Aucune mutation, sans effet de bords
Un peu de LINQ : sélectionner une
propriété
 Avant

 Après

public List<int> MutableGetXs(List<Point> points)
{
var xs = new List<int>();
foreach (var point in points)
{
xs.Add(point.X);
}
return xs;
}

public List<int> ImmutableGetXs(List<Point> points)
{
return points.Select(p => p.X).ToList();
}
Exercice
 Refactoriser le code suivant pour le rendre immutable
public class MyPoint
{
public double X { get; set; }
public double Y { get; set; }
public static void Translate(List<MyPoint>
points, double dx, double dy)
{
foreach (var point in points)
{
point.X += dx;
point.Y += dy;
}
}
public override bool Equals(object obj)
{
var point = (MyPoint)obj;
return point.X == this.X && point.Y ==
this.Y;
}
}

[TestClass]
public class MyPointTests
{
[TestMethod]
public void TestTranslate()
{
var points = new List<MyPoint>() {
new MyPoint() { X = 1, Y = 2 },
new MyPoint() { X = -1, Y = 0 }
};
MyPoint.Translate(points, 1, 2);

var expected = new List<MyPoint>() {
new MyPoint() { X = 2, Y = 4 },
new MyPoint() { X = 0, Y = 2 }
};
CollectionAssert.AreEqual(expected, points);
}
}
Correction
public class MyPoint
{
private readonly double _x;
public double X { get { return _x; } }

private readonly double _y;
public double Y { get { return _y; } }
public MyPoint(double x, double y)
{
this._x = x;
this._y = y;
}

[TestClass]
public class MyPointTests
{
[TestMethod]
public void TestTranslate()
{
var points = new List<MyPoint>()
{
new MyPoint(1, 2),
new MyPoint(-1, 0)
};
var actual = MyPoint.Translate(points, 1, 2);

var expected = new List<MyPoint>()
{
new MyPoint(2, 4),
new MyPoint(0, 2)
};

public static List<MyPoint> Translate(List<MyPoint>
points, double dx, double dy)
{
return points.Select(p => new MyPoint(p.X + dx,
p.Y + dy)).ToList();
}

CollectionAssert.AreEqual(expected, actual);
}

public override bool Equals(object obj)
{
var point = (MyPoint)obj;
return point.X == this.X && point.Y == this.Y;
}
}

}
Conclusion
 Les concepts de pureté et d’immutabilité proviennent de la
programmation fonctionnelle
 Concepts puissants qui empêchent beaucoup d’erreurs et d’effet de bords
 Demande des ajustements dans la façon de coder, et dans l’approche
des problèmes
 Ces concepts sont applicables dans tous les langages, objets ou
procéduraux
5. Analyse statique
L’analyse du code par des systèmes tiers
La revue du code
 Via des personnes : camarade, collègues, forums
 Extreme Programming (XP) pratique le Pair programming :
deux paires d'yeux valent mieux qu'une. Se passe
pendant l’écriture, couteuse en ressource humaine
 Code review : Se passe à postériori de l’écriture, moins
couteuse
 http://www.developpez.net/forums/;
http://stackoverflow.com/;
http://codereview.stackexchange.com/

 Via des logiciels
 ReSharper, NDepend, Coverity, etc.
 http://en.wikipedia.org/wiki/List_of_tools_for_static_code_
analysis
Un exemple

 Capture d’écran d’un rapport NDepend
Purity – Immutability – Side-Effects

 Capture d’écran d’un rapport NDepend
Les outils d’analyse statique
 Analyse du code basé sur un ensemble de règles
 Propose des avertissements dans les domaines : convention de nommage,
design, architecture, code mort, etc.
 Permet la modification et l’ajout de nouvelles règles
 Disponible dans tout les langages, du gratuit au plus cher
Programmation par contrat
 Permet de définir des pré conditions, des post conditions et des invariants
pour chaque fonction
 Provient du langage Eiffel (1986) qui le supporte nativement
 Supporté à base de plugin dans Visual Studio (Code Contracts) de
manière statique
 Plusieurs implémentations existe dans les autres langages, analyse
dynamique uniquement
 Java : Cofoja, SpringContracts
 PHP : Praspel

 CF http://en.wikipedia.org/wiki/Design_by_contract
Code Contracts
 Vérification statique à base de Warning
 Vérification dynamique = lancement d’Exception

 Générateur de documentation
Exemple Code Contracts
public class Test
{
private object _value2 = "";
public object TestMethod(object value, object value2)
{
Contract.Requires(value != null); // Static Warning && Runtime Exception en entrée
Contract.Ensures(Contract.Result<object>() != null); // Static Warning && Runtime Exception en sortie
this._value2 = value2;
return null; // Static Warning
}
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(this._value2 != null); // Static Warning && Runtime Exception en sortie
}
}
static void Main(string[] args)
{
var test = new Test();
test.TestMethod(null, null); // Static Warning
}
Qualité logicielle
Conclusion
 Avoir en tête les fonctionnalités demandées, c’est bien
 Avoir en tête la qualité et les fonctionnalités, c’est mieux

 Des efforts aujourd’hui pour des effets demain
 La qualité en informatique est comme la qualité en général, un
investissement à long terme
 La qualité demande du temps. « Vite fait bien fait » n’existe pas, fast code
= dirty code
Bibliographie
 Code Complete de Steve McConnell
 Refactoring: Improving the Design of Existing Code de Martin Fowler

 Learn You a Haskell for Great Good!: A Beginner's Guide de Miran Lipovaca
 Clean Code: A Handbook of Agile Software Craftsmanship de Robert C.
Martin

Contenu connexe

Tendances

Programmation orientee aspect 201401 - Ensim
Programmation orientee aspect 201401 - EnsimProgrammation orientee aspect 201401 - Ensim
Programmation orientee aspect 201401 - EnsimLaurent Broudoux
 
Test driven development v0.2 20121221
Test driven development v0.2 20121221Test driven development v0.2 20121221
Test driven development v0.2 20121221Frédéric Delorme
 
Traits : de la théorie à la pratique
Traits : de la théorie à la pratiqueTraits : de la théorie à la pratique
Traits : de la théorie à la pratiqueFrederic Hardy
 
Cours algorithme
Cours algorithmeCours algorithme
Cours algorithmebadr zaimi
 
Exposé qualité et test
Exposé qualité et test Exposé qualité et test
Exposé qualité et test Imen Turki
 
les metriques de processus, de produit et de qualité
les metriques de processus, de produit et de qualitéles metriques de processus, de produit et de qualité
les metriques de processus, de produit et de qualitésoregh
 
Soirée du Test Logiciel - Intelligence Artificielle dans le test - J. VAN QUA...
Soirée du Test Logiciel - Intelligence Artificielle dans le test - J. VAN QUA...Soirée du Test Logiciel - Intelligence Artificielle dans le test - J. VAN QUA...
Soirée du Test Logiciel - Intelligence Artificielle dans le test - J. VAN QUA...TelecomValley
 
Intro sur les tests unitaires
Intro sur les tests unitairesIntro sur les tests unitaires
Intro sur les tests unitairesPHPPRO
 
Programmation orienté aspect
Programmation orienté aspectProgrammation orienté aspect
Programmation orienté aspectmeriem sari
 
Test de logiciels
Test de logiciels Test de logiciels
Test de logiciels Bilel Abed
 
Test unitaire
Test unitaireTest unitaire
Test unitaireIsenDev
 
Types de tests vs techniques de tests
Types de tests vs techniques de testsTypes de tests vs techniques de tests
Types de tests vs techniques de testsSabrine MASTOURA
 
Formation Extreme Programming, Tests unitaires, travail collaboratif
Formation Extreme Programming, Tests unitaires, travail collaboratifFormation Extreme Programming, Tests unitaires, travail collaboratif
Formation Extreme Programming, Tests unitaires, travail collaboratifkemenaran
 

Tendances (20)

Programmation orientee aspect 201401 - Ensim
Programmation orientee aspect 201401 - EnsimProgrammation orientee aspect 201401 - Ensim
Programmation orientee aspect 201401 - Ensim
 
Bbl sur les tests
Bbl sur les testsBbl sur les tests
Bbl sur les tests
 
Test driven development v0.2 20121221
Test driven development v0.2 20121221Test driven development v0.2 20121221
Test driven development v0.2 20121221
 
Qualité de code et bonnes pratiques
Qualité de code et bonnes pratiquesQualité de code et bonnes pratiques
Qualité de code et bonnes pratiques
 
Et4 4 testinformel
Et4 4 testinformelEt4 4 testinformel
Et4 4 testinformel
 
Traits : de la théorie à la pratique
Traits : de la théorie à la pratiqueTraits : de la théorie à la pratique
Traits : de la théorie à la pratique
 
Cours algorithme
Cours algorithmeCours algorithme
Cours algorithme
 
J Unit
J UnitJ Unit
J Unit
 
Exposé qualité et test
Exposé qualité et test Exposé qualité et test
Exposé qualité et test
 
les metriques de processus, de produit et de qualité
les metriques de processus, de produit et de qualitéles metriques de processus, de produit et de qualité
les metriques de processus, de produit et de qualité
 
Cours algorithmique02
Cours algorithmique02Cours algorithmique02
Cours algorithmique02
 
Soirée du Test Logiciel - Intelligence Artificielle dans le test - J. VAN QUA...
Soirée du Test Logiciel - Intelligence Artificielle dans le test - J. VAN QUA...Soirée du Test Logiciel - Intelligence Artificielle dans le test - J. VAN QUA...
Soirée du Test Logiciel - Intelligence Artificielle dans le test - J. VAN QUA...
 
Intro sur les tests unitaires
Intro sur les tests unitairesIntro sur les tests unitaires
Intro sur les tests unitaires
 
Programmation orienté aspect
Programmation orienté aspectProgrammation orienté aspect
Programmation orienté aspect
 
Test de logiciels
Test de logiciels Test de logiciels
Test de logiciels
 
Test unitaire
Test unitaireTest unitaire
Test unitaire
 
Types de tests vs techniques de tests
Types de tests vs techniques de testsTypes de tests vs techniques de tests
Types de tests vs techniques de tests
 
Metrique
MetriqueMetrique
Metrique
 
Formation Extreme Programming, Tests unitaires, travail collaboratif
Formation Extreme Programming, Tests unitaires, travail collaboratifFormation Extreme Programming, Tests unitaires, travail collaboratif
Formation Extreme Programming, Tests unitaires, travail collaboratif
 
Algorithme
AlgorithmeAlgorithme
Algorithme
 

En vedette

Intégration continue
Intégration continueIntégration continue
Intégration continueKlee Group
 
Automatisation des tests
Automatisation des testsAutomatisation des tests
Automatisation des testsZhu Wei QI
 
Génie Logiciels : Introduction aux architectures
Génie Logiciels : Introduction aux architecturesGénie Logiciels : Introduction aux architectures
Génie Logiciels : Introduction aux architecturesMohammed Amine Mostefai
 
Tests ihm automatises avec selenium
Tests ihm automatises avec seleniumTests ihm automatises avec selenium
Tests ihm automatises avec seleniumsojavawest
 
Thèse Quantification sur cône de lumière
Thèse Quantification sur cône de lumièreThèse Quantification sur cône de lumière
Thèse Quantification sur cône de lumièreStéphane Salmons
 
Mémo Pilotage PPL(A) DR400 1.8
Mémo Pilotage PPL(A) DR400 1.8Mémo Pilotage PPL(A) DR400 1.8
Mémo Pilotage PPL(A) DR400 1.8Stéphane Salmons
 
Introduction au génie logiciel 1.2
Introduction au génie logiciel 1.2Introduction au génie logiciel 1.2
Introduction au génie logiciel 1.2Stéphane Salmons
 
Décryptage loi trantion énergétique
Décryptage loi trantion énergétiqueDécryptage loi trantion énergétique
Décryptage loi trantion énergétiqueRAC-F
 
Note giec wgiii
Note giec wgiiiNote giec wgiii
Note giec wgiiiRAC-F
 
BigData Paris 2014 - Enjeux Sociaux
BigData Paris 2014 - Enjeux SociauxBigData Paris 2014 - Enjeux Sociaux
BigData Paris 2014 - Enjeux SociauxElian CARSENAT
 
Pass Repreneur Bpifrance Présentation
Pass Repreneur Bpifrance PrésentationPass Repreneur Bpifrance Présentation
Pass Repreneur Bpifrance PrésentationBecuwe Maëlle
 
Transport mise-en-place-immédiate-de-l-eco-taxe-poids-lourds2014
Transport mise-en-place-immédiate-de-l-eco-taxe-poids-lourds2014Transport mise-en-place-immédiate-de-l-eco-taxe-poids-lourds2014
Transport mise-en-place-immédiate-de-l-eco-taxe-poids-lourds2014RAC-F
 
Préparation crêpes
Préparation crêpesPréparation crêpes
Préparation crêpesMoiAmalia
 
Rapport d activites_eco_ecolo_2013
Rapport d activites_eco_ecolo_2013Rapport d activites_eco_ecolo_2013
Rapport d activites_eco_ecolo_2013RAC-F
 

En vedette (20)

Intégration continue
Intégration continueIntégration continue
Intégration continue
 
Automatisation des tests
Automatisation des testsAutomatisation des tests
Automatisation des tests
 
Génie Logiciels : Introduction aux architectures
Génie Logiciels : Introduction aux architecturesGénie Logiciels : Introduction aux architectures
Génie Logiciels : Introduction aux architectures
 
Génie Logiciel : les tests
Génie Logiciel : les testsGénie Logiciel : les tests
Génie Logiciel : les tests
 
Tests ihm automatises avec selenium
Tests ihm automatises avec seleniumTests ihm automatises avec selenium
Tests ihm automatises avec selenium
 
Thèse Quantification sur cône de lumière
Thèse Quantification sur cône de lumièreThèse Quantification sur cône de lumière
Thèse Quantification sur cône de lumière
 
Mémo Pilotage PPL(A) DR400 1.8
Mémo Pilotage PPL(A) DR400 1.8Mémo Pilotage PPL(A) DR400 1.8
Mémo Pilotage PPL(A) DR400 1.8
 
Introduction au génie logiciel 1.2
Introduction au génie logiciel 1.2Introduction au génie logiciel 1.2
Introduction au génie logiciel 1.2
 
Décryptage loi trantion énergétique
Décryptage loi trantion énergétiqueDécryptage loi trantion énergétique
Décryptage loi trantion énergétique
 
Maroc 31 mai
Maroc 31 mai Maroc 31 mai
Maroc 31 mai
 
Note giec wgiii
Note giec wgiiiNote giec wgiii
Note giec wgiii
 
BigData Paris 2014 - Enjeux Sociaux
BigData Paris 2014 - Enjeux SociauxBigData Paris 2014 - Enjeux Sociaux
BigData Paris 2014 - Enjeux Sociaux
 
Pass Repreneur Bpifrance Présentation
Pass Repreneur Bpifrance PrésentationPass Repreneur Bpifrance Présentation
Pass Repreneur Bpifrance Présentation
 
Rapport annuel fr-lo res
Rapport annuel fr-lo resRapport annuel fr-lo res
Rapport annuel fr-lo res
 
Dbv technologies en_image
Dbv technologies en_imageDbv technologies en_image
Dbv technologies en_image
 
Pour estevan
Pour estevanPour estevan
Pour estevan
 
Transport mise-en-place-immédiate-de-l-eco-taxe-poids-lourds2014
Transport mise-en-place-immédiate-de-l-eco-taxe-poids-lourds2014Transport mise-en-place-immédiate-de-l-eco-taxe-poids-lourds2014
Transport mise-en-place-immédiate-de-l-eco-taxe-poids-lourds2014
 
Préparation crêpes
Préparation crêpesPréparation crêpes
Préparation crêpes
 
Liberation
Liberation Liberation
Liberation
 
Rapport d activites_eco_ecolo_2013
Rapport d activites_eco_ecolo_2013Rapport d activites_eco_ecolo_2013
Rapport d activites_eco_ecolo_2013
 

Similaire à Qualité logicielle

Visual Studio 2008 Overview
Visual Studio 2008 OverviewVisual Studio 2008 Overview
Visual Studio 2008 OverviewGregory Renard
 
Domain-Specific Languages avec Groovy
Domain-Specific Languages avec GroovyDomain-Specific Languages avec Groovy
Domain-Specific Languages avec GroovyGuillaume Laforge
 
Java 9 modulo les modules devoxx fr 2017
Java 9 modulo les modules devoxx fr 2017Java 9 modulo les modules devoxx fr 2017
Java 9 modulo les modules devoxx fr 2017Jean-Michel Doudoux
 
L’environnement de programmation fonctionnelle DrRacket
L’environnement de programmation fonctionnelle DrRacketL’environnement de programmation fonctionnelle DrRacket
L’environnement de programmation fonctionnelle DrRacketStéphane Legrand
 
Performance et optimisation de PrestaShop
Performance et optimisation de PrestaShopPerformance et optimisation de PrestaShop
Performance et optimisation de PrestaShopPrestaShop
 
La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !
La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !
La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !Paris Salesforce Developer Group
 
Notions de base de JavaScript
Notions de base de JavaScriptNotions de base de JavaScript
Notions de base de JavaScriptKristen Le Liboux
 
Design Pattern introduction
Design Pattern introductionDesign Pattern introduction
Design Pattern introductionneuros
 
Design Patterns Java
Design Patterns JavaDesign Patterns Java
Design Patterns JavaVINOT Bernard
 
Développer en natif avec C++11
Développer en natif avec C++11Développer en natif avec C++11
Développer en natif avec C++11Microsoft
 
Design poo togo_jug_final
Design poo togo_jug_finalDesign poo togo_jug_final
Design poo togo_jug_finalagnes_crepet
 
Design poo togo_jug_final
Design poo togo_jug_finalDesign poo togo_jug_final
Design poo togo_jug_finalDuchess France
 
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniterAtsé François-Xavier KOBON
 
Soutenance Zend Framework vs Symfony
Soutenance Zend Framework vs SymfonySoutenance Zend Framework vs Symfony
Soutenance Zend Framework vs SymfonyVincent Composieux
 
Analyse et optimisation des performances du moteur SQL Serveur
Analyse et optimisation des performances du moteur SQL ServeurAnalyse et optimisation des performances du moteur SQL Serveur
Analyse et optimisation des performances du moteur SQL ServeurMicrosoft Technet France
 
RefCard Tests sur tous les fronts
RefCard Tests sur tous les frontsRefCard Tests sur tous les fronts
RefCard Tests sur tous les frontsOCTO Technology
 
AOP.pptx
AOP.pptxAOP.pptx
AOP.pptxManalAg
 

Similaire à Qualité logicielle (20)

Visual Studio 2008 Overview
Visual Studio 2008 OverviewVisual Studio 2008 Overview
Visual Studio 2008 Overview
 
Domain-Specific Languages avec Groovy
Domain-Specific Languages avec GroovyDomain-Specific Languages avec Groovy
Domain-Specific Languages avec Groovy
 
Java 9 modulo les modules devoxx fr 2017
Java 9 modulo les modules devoxx fr 2017Java 9 modulo les modules devoxx fr 2017
Java 9 modulo les modules devoxx fr 2017
 
C# 7 - Nouveautés
C# 7 - NouveautésC# 7 - Nouveautés
C# 7 - Nouveautés
 
L’environnement de programmation fonctionnelle DrRacket
L’environnement de programmation fonctionnelle DrRacketL’environnement de programmation fonctionnelle DrRacket
L’environnement de programmation fonctionnelle DrRacket
 
Tutoriel java
Tutoriel javaTutoriel java
Tutoriel java
 
Performance et optimisation de PrestaShop
Performance et optimisation de PrestaShopPerformance et optimisation de PrestaShop
Performance et optimisation de PrestaShop
 
La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !
La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !
La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !
 
Notions de base de JavaScript
Notions de base de JavaScriptNotions de base de JavaScript
Notions de base de JavaScript
 
Design Pattern introduction
Design Pattern introductionDesign Pattern introduction
Design Pattern introduction
 
Design Patterns Java
Design Patterns JavaDesign Patterns Java
Design Patterns Java
 
Développer en natif avec C++11
Développer en natif avec C++11Développer en natif avec C++11
Développer en natif avec C++11
 
Design poo togo_jug_final
Design poo togo_jug_finalDesign poo togo_jug_final
Design poo togo_jug_final
 
Design poo togo_jug_final
Design poo togo_jug_finalDesign poo togo_jug_final
Design poo togo_jug_final
 
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
 
Soutenance Zend Framework vs Symfony
Soutenance Zend Framework vs SymfonySoutenance Zend Framework vs Symfony
Soutenance Zend Framework vs Symfony
 
Pensez objets avec java
Pensez objets avec javaPensez objets avec java
Pensez objets avec java
 
Analyse et optimisation des performances du moteur SQL Serveur
Analyse et optimisation des performances du moteur SQL ServeurAnalyse et optimisation des performances du moteur SQL Serveur
Analyse et optimisation des performances du moteur SQL Serveur
 
RefCard Tests sur tous les fronts
RefCard Tests sur tous les frontsRefCard Tests sur tous les fronts
RefCard Tests sur tous les fronts
 
AOP.pptx
AOP.pptxAOP.pptx
AOP.pptx
 

Dernier

Vulnérabilité numérique d’usage : un enjeu pour l’aide à la réussitepdf
Vulnérabilité numérique d’usage : un enjeu pour l’aide à la réussitepdfVulnérabilité numérique d’usage : un enjeu pour l’aide à la réussitepdf
Vulnérabilité numérique d’usage : un enjeu pour l’aide à la réussitepdfSylvianeBachy
 
DIGNITAS INFINITA - DIGNITÉ HUMAINE; déclaration du dicastère .pptx
DIGNITAS INFINITA - DIGNITÉ HUMAINE; déclaration du dicastère .pptxDIGNITAS INFINITA - DIGNITÉ HUMAINE; déclaration du dicastère .pptx
DIGNITAS INFINITA - DIGNITÉ HUMAINE; déclaration du dicastère .pptxMartin M Flynn
 
Chana Orloff.pptx Sculptrice franco-ukranienne
Chana Orloff.pptx Sculptrice franco-ukranienneChana Orloff.pptx Sculptrice franco-ukranienne
Chana Orloff.pptx Sculptrice franco-ukranienneTxaruka
 
Faut-il avoir peur de la technique ? (G. Gay-Para)
Faut-il avoir peur de la technique ? (G. Gay-Para)Faut-il avoir peur de la technique ? (G. Gay-Para)
Faut-il avoir peur de la technique ? (G. Gay-Para)Gabriel Gay-Para
 
L'Unité de Spiritualité Eudiste se joint à toute l'Église Universelle et en p...
L'Unité de Spiritualité Eudiste se joint à toute l'Église Universelle et en p...L'Unité de Spiritualité Eudiste se joint à toute l'Église Universelle et en p...
L'Unité de Spiritualité Eudiste se joint à toute l'Église Universelle et en p...Unidad de Espiritualidad Eudista
 
Copilot your everyday AI companion- OFFICE 365-
Copilot your everyday AI companion- OFFICE 365-Copilot your everyday AI companion- OFFICE 365-
Copilot your everyday AI companion- OFFICE 365-Majida Antonios, M.Ed.
 
Bibdoc 2024 - Les intelligences artificielles en bibliotheque.pdf
Bibdoc 2024 - Les intelligences artificielles en bibliotheque.pdfBibdoc 2024 - Les intelligences artificielles en bibliotheque.pdf
Bibdoc 2024 - Les intelligences artificielles en bibliotheque.pdfAtelier Canopé 37 - Tours
 
Bibdoc 2024 - Sobriete numerique en bibliotheque et centre de documentation.pdf
Bibdoc 2024 - Sobriete numerique en bibliotheque et centre de documentation.pdfBibdoc 2024 - Sobriete numerique en bibliotheque et centre de documentation.pdf
Bibdoc 2024 - Sobriete numerique en bibliotheque et centre de documentation.pdfAtelier Canopé 37 - Tours
 
Pas de vagues. pptx Film français
Pas de vagues.  pptx   Film     françaisPas de vagues.  pptx   Film     français
Pas de vagues. pptx Film françaisTxaruka
 
Calendrier de la semaine du 8 au 12 avril
Calendrier de la semaine du 8 au 12 avrilCalendrier de la semaine du 8 au 12 avril
Calendrier de la semaine du 8 au 12 avrilfrizzole
 
Bibdoc 2024 - L’Éducation aux Médias et à l’Information face à l’intelligence...
Bibdoc 2024 - L’Éducation aux Médias et à l’Information face à l’intelligence...Bibdoc 2024 - L’Éducation aux Médias et à l’Information face à l’intelligence...
Bibdoc 2024 - L’Éducation aux Médias et à l’Information face à l’intelligence...Atelier Canopé 37 - Tours
 
Apprendre avec des top et nano influenceurs
Apprendre avec des top et nano influenceursApprendre avec des top et nano influenceurs
Apprendre avec des top et nano influenceursStagiaireLearningmat
 
Newsletter SPW Agriculture en province du Luxembourg du 10-04-24
Newsletter SPW Agriculture en province du Luxembourg du 10-04-24Newsletter SPW Agriculture en province du Luxembourg du 10-04-24
Newsletter SPW Agriculture en province du Luxembourg du 10-04-24BenotGeorges3
 
Aux origines de la sociologie : du XIXème au début XX ème siècle
Aux origines de la sociologie : du XIXème au début XX ème siècleAux origines de la sociologie : du XIXème au début XX ème siècle
Aux origines de la sociologie : du XIXème au début XX ème siècleAmar LAKEL, PhD
 
La Base unique départementale - Quel bilan, au bout de 5 ans .pdf
La Base unique départementale - Quel bilan, au bout de 5 ans .pdfLa Base unique départementale - Quel bilan, au bout de 5 ans .pdf
La Base unique départementale - Quel bilan, au bout de 5 ans .pdfbdp12
 
Présentation - Initiatives - CECOSDA - OIF - Fact Checking.pptx
Présentation - Initiatives - CECOSDA - OIF - Fact Checking.pptxPrésentation - Initiatives - CECOSDA - OIF - Fact Checking.pptx
Présentation - Initiatives - CECOSDA - OIF - Fact Checking.pptxJCAC
 

Dernier (17)

Vulnérabilité numérique d’usage : un enjeu pour l’aide à la réussitepdf
Vulnérabilité numérique d’usage : un enjeu pour l’aide à la réussitepdfVulnérabilité numérique d’usage : un enjeu pour l’aide à la réussitepdf
Vulnérabilité numérique d’usage : un enjeu pour l’aide à la réussitepdf
 
DIGNITAS INFINITA - DIGNITÉ HUMAINE; déclaration du dicastère .pptx
DIGNITAS INFINITA - DIGNITÉ HUMAINE; déclaration du dicastère .pptxDIGNITAS INFINITA - DIGNITÉ HUMAINE; déclaration du dicastère .pptx
DIGNITAS INFINITA - DIGNITÉ HUMAINE; déclaration du dicastère .pptx
 
Chana Orloff.pptx Sculptrice franco-ukranienne
Chana Orloff.pptx Sculptrice franco-ukranienneChana Orloff.pptx Sculptrice franco-ukranienne
Chana Orloff.pptx Sculptrice franco-ukranienne
 
Faut-il avoir peur de la technique ? (G. Gay-Para)
Faut-il avoir peur de la technique ? (G. Gay-Para)Faut-il avoir peur de la technique ? (G. Gay-Para)
Faut-il avoir peur de la technique ? (G. Gay-Para)
 
L'Unité de Spiritualité Eudiste se joint à toute l'Église Universelle et en p...
L'Unité de Spiritualité Eudiste se joint à toute l'Église Universelle et en p...L'Unité de Spiritualité Eudiste se joint à toute l'Église Universelle et en p...
L'Unité de Spiritualité Eudiste se joint à toute l'Église Universelle et en p...
 
Copilot your everyday AI companion- OFFICE 365-
Copilot your everyday AI companion- OFFICE 365-Copilot your everyday AI companion- OFFICE 365-
Copilot your everyday AI companion- OFFICE 365-
 
Bibdoc 2024 - Les intelligences artificielles en bibliotheque.pdf
Bibdoc 2024 - Les intelligences artificielles en bibliotheque.pdfBibdoc 2024 - Les intelligences artificielles en bibliotheque.pdf
Bibdoc 2024 - Les intelligences artificielles en bibliotheque.pdf
 
Bibdoc 2024 - Sobriete numerique en bibliotheque et centre de documentation.pdf
Bibdoc 2024 - Sobriete numerique en bibliotheque et centre de documentation.pdfBibdoc 2024 - Sobriete numerique en bibliotheque et centre de documentation.pdf
Bibdoc 2024 - Sobriete numerique en bibliotheque et centre de documentation.pdf
 
Pas de vagues. pptx Film français
Pas de vagues.  pptx   Film     françaisPas de vagues.  pptx   Film     français
Pas de vagues. pptx Film français
 
Calendrier de la semaine du 8 au 12 avril
Calendrier de la semaine du 8 au 12 avrilCalendrier de la semaine du 8 au 12 avril
Calendrier de la semaine du 8 au 12 avril
 
Bibdoc 2024 - L’Éducation aux Médias et à l’Information face à l’intelligence...
Bibdoc 2024 - L’Éducation aux Médias et à l’Information face à l’intelligence...Bibdoc 2024 - L’Éducation aux Médias et à l’Information face à l’intelligence...
Bibdoc 2024 - L’Éducation aux Médias et à l’Information face à l’intelligence...
 
Apprendre avec des top et nano influenceurs
Apprendre avec des top et nano influenceursApprendre avec des top et nano influenceurs
Apprendre avec des top et nano influenceurs
 
Bulletin des bibliotheques Burkina Faso mars 2024
Bulletin des bibliotheques Burkina Faso mars 2024Bulletin des bibliotheques Burkina Faso mars 2024
Bulletin des bibliotheques Burkina Faso mars 2024
 
Newsletter SPW Agriculture en province du Luxembourg du 10-04-24
Newsletter SPW Agriculture en province du Luxembourg du 10-04-24Newsletter SPW Agriculture en province du Luxembourg du 10-04-24
Newsletter SPW Agriculture en province du Luxembourg du 10-04-24
 
Aux origines de la sociologie : du XIXème au début XX ème siècle
Aux origines de la sociologie : du XIXème au début XX ème siècleAux origines de la sociologie : du XIXème au début XX ème siècle
Aux origines de la sociologie : du XIXème au début XX ème siècle
 
La Base unique départementale - Quel bilan, au bout de 5 ans .pdf
La Base unique départementale - Quel bilan, au bout de 5 ans .pdfLa Base unique départementale - Quel bilan, au bout de 5 ans .pdf
La Base unique départementale - Quel bilan, au bout de 5 ans .pdf
 
Présentation - Initiatives - CECOSDA - OIF - Fact Checking.pptx
Présentation - Initiatives - CECOSDA - OIF - Fact Checking.pptxPrésentation - Initiatives - CECOSDA - OIF - Fact Checking.pptx
Présentation - Initiatives - CECOSDA - OIF - Fact Checking.pptx
 

Qualité logicielle

  • 2. Introduction  Vous savez coder : lire et écrire un fichier, afficher un résultat à l’écran, lancer plusieurs Threads, manipuler des listes, etc.  Etes vous attentifs à la qualité de votre code ?  Un logiciel ne se résume pas à ses fonctionnalités  Son potentiel de croissance est au moins aussi important que ses fonctionnalités  Un code de qualité est tourné vers le futur : maintenable, modulable
  • 3. Objectifs  Etre capable de reconnaitre le manque de qualité d’un code  Etre capable d’appliquer les méthodes de refactoring pour augmenter la qualité  Comprendre les enjeux de la qualité logicielle  Connaitre les outils applicables pour écrire un code de qualité
  • 4. Sommaire 1. Mesure de la qualité 2. Le Refactoring 3. Les principes S.O.L.I.D. 4. Initiation à la programmation fonctionnelle 5. Analyse statique 6. Programmation par contrat
  • 5. 1. Mesure de la qualité
  • 6. La théorie : Norme ISO 9126 Software engineering — Product quality  Functionality : The existence of a set of functions and their specified properties. The functions are those that satisfy stated or implied needs.   Reliability : The capability of software to maintain its level of performance under stated conditions for a stated period of time.   Time Behaviour, Resource Utilization, Efficiency Compliance Maintainability : The effort needed to make specified modifications.   Understandability, Learnability, Operability, Attractiveness, Usability Compliance Efficiency : The relationship between the level of performance of the software and the amount of resources used, under stated conditions.   Maturity, Fault Tolerance, Recoverability, Reliability Compliance Usability : The effort needed for use, and on the individual assessment of such use, by a stated or implied set of users.   Suitability, Accuracy, Interoperability, Security, Functionality Compliance Analyzability, Changeability, Stability, Testability, Maintainability Compliance Portability : The ability of software to be transferred from one environment to another.  Adaptability, Installability, Co-Existence, Replaceability, Portability Compliance  Source : http://en.wikipedia.org/wiki/ISO/IEC_9126
  • 7. En pratique  Fonctionnel  Maintenable  KISS : Keep It Simple Stupid  YAGNI : You Ain’t Gonna Need It  DRY : Don’t Repeat Yourself  Performant (Théorie de la complexité)  Robuste (Parallélisable, Portable)  Testable (Via les tests unitaires)
  • 8. Fonctionnel  Développer les fonctionnalités demandées
  • 9. Maintenable  Simplicité, simplicité, simplicité  Lisibilité  Pas de code spaghetti  Ne soyez pas un « Astronaute Architecte » = Ne surdésigner pas le model  Ne vous répétez pas, n’écrivez jamais deux fois le même code
  • 10. Performant  Soyez conscient de la complexité de votre algorithme  O(1) > O(log n) > O(n) > O(n log n) > O(n²)
  • 11. Robuste  Comment réagi votre logiciel « au bord »  Et si le réseau tombe ?  Et si l’utilisateur rentre de mauvaises données ?  Et si les données reçues sont dans un mauvais format ?  Fail fast => Valider toujours et échouer rapidement
  • 12. Testable  La couverture des tests unitaires doit approcher les 100%  Réduit les dépendances  Diminue les régressions
  • 14. Le refactoring, c’est quoi ?  Définition : la modification du code d’un logiciel dans le but de le rendre plus simple à comprendre et à modifier, sans changer son comportement observable  Simplifier le code  Accroitre sa lisibilité  Un code est écrit 1 fois et lu 10 fois  80% du temps est passé à la maintenance, donc la relecture  Gagner en robustesse  Du temps investi aujourd’hui pour une maintenance plus simple demain  Ne modifie pas les fonctionnalités existantes
  • 15. (Re)Factorisation d’une identité remarquable a² + 2ab + b² (a + b)²  a = 2, b = 4  a = 2, b = 4  2² + 2 * 2 * 4 + 4² = ?  (2 + 4)² = 36
  • 17. Quelques principes 1. Renommage 2. Découper les fonctions 3. Réduire les paramètres 4. Réduire le scope des variables 5. Rendre les objets immutables 6. Eviter les négations et supprimer les doubles négation 7. Introduire des variables temporaires pour des expressions complexes 8. Ne pas utiliser la même variable pour autres chose 9. Séparer les niveaux (layers) d’abstraction 10. Loi de Demeter
  • 18. 1. Renommage  Un bon nom doit être dicible par téléphone  Notation PascalCase pour les classes et méthodes, camelCase pour les variables (en C#)  Doit décrire précisément l’action ou l’état représenté  Suivre les conventions de nommages de son langage (Java != C# != PHP), ou de son entreprise si elles existent The name of a method does not reveal its purpose. Change the name of the method.
  • 19. 2. Découper les fonctions  Diviser pour régner, mieux vaut plusieurs petites fonctions qu’une seule grosse  Une fonction ne devrait jamais dépasser quelques dizaines de lignes void printOwing() { printBanner(); //print details System.out.println ("name: " + _name); System.out.println ("amount " + getOutstanding()); } void printOwing() { printBanner(); printDetails(getOutstanding()); } void printDetails (double outstanding) { System.out.println ("name: " + _name); System.out.println ("amount " + outstanding); }
  • 20. 3. Réduire le scope des variables  Une variable doit être déclarer au plus proche de son utilisation, dans le scope (contexte) le plus faible  Permet de suivre l’algorithme plus facilement. Le cerveau ne peut pas retenir plus de 6-7 variables  Implique d’éviter au maximum les variables static qui ont un scope global à toute l’application
  • 21. 3. Réduire le scope des variables public int Foo(int j) { int i = 2; int a; if (j > 3) { a = i * i; } else { a = 0; } return a; } Scope de i public int Foo(int j) { int a; if (j > 3) { int i = 2; a = i * i; } else { a = 0; } return a; } Scope de i
  • 22. 4. Réduire le nombre de paramètres  Le nombre de paramètres d’une méthode ne devrait jamais dépasser 3 ou 4  Grouper ensemble les paramètres qui ont un sens commun You have a group of parameters that naturally go together. Replace them with an object.
  • 23. 5. Rendre les objets immutables  Un objet sans setters (immutable) est plus simple à manipuler et plus sécurisant (CF la programmation fonctionnelle)  Peut être passer à des tiers sans effet de bords  Laisser les mutants à la science fiction, pas à la science informatique
  • 24. 5. Rendre les objets immutables public class MyPoint { private double _x; public class MyPoint { private readonly double _x; public double X { get { return _x; } set { _x = value; } } private double _y; public double X { get { return _x; } } private readonly double _y; public double Y { get { return _y; } } public double Y { get { return _y; } set { _y = value; } } public MyPoint(double x, double y) { this.X = x; this.Y = y; } } public MyPoint(double x, double y) { this._x = x; this._y = y; } }
  • 25. 6. Eviter les négations et les doubles négation  La lecture est toujours plus simple dans le sens positif que dans le sens négatif double foo; if(this.HasValue == false) foo = 0; else foo = 1; double foo; if(this.HaveValue) foo = 1; else foo = 0; if(!this.NotFound()) if(this.Found())
  • 26. 7. Introduire des variables temporaires pour des expressions complexes  Condenser un trop plein d’informations dans une variable nommée if ( (platform.toUpperCase().indexOf("MAC") > -1) && (browser.toUpperCase().indexOf("IE") > -1) && wasInitialized() && resize > 0 ) { // do something } final boolean isMacOs = platform.toUpperCase().indexOf("MAC") > -1; final boolean isIEBrowser = browser.toUpperCase().indexOf("IE") > -1; final boolean wasResized = resize > 0; if (isMacOs && isIEBrowser && wasInitialized() && wasResized) { // do something }
  • 27. 8. Ne pas utiliser la même variable pour 2 concepts différents  Garder en tête la signification d’une variable est difficile, encore plus si elle change en cours de route  Mieux vaut créer une nouvelle variable  L’idéal est qu’une variable doit être assignée une seule fois (paradigme de la programmation fonctionnelle) double temp = 2 * (_height + _width); System.out.println (temp); temp = _height * _width; System.out.println (temp); final double perimeter = 2 * (_height + _width); System.out.println (perimeter); final double area = _height * _width; System.out.println (area);
  • 28. 9. Séparer les niveaux (layers) d’abstraction  Identifier et séparer les différentes couches de l’application  Généralement se sont les suivantes  Couche métier (algorithme, logique = BML, Buisness Model Layer)  Couche de présentation (Vue/View)  Couche d’accès aux données (DAL, Data Access Layer)  Voir le Pattern MVC pour un tel découpage (Model Vue Controller)
  • 29. 10. Loi de Demeter  L’antipattern : Feature Envy  var c = a.GetB().GetC();  Augmente le couplage  Définition : Ne parlez qu’à vos amis directs  Vous pouvez jouer avec vous même  Vous pouvez jouer avec vos jouets  Vous pouvez jouer avec les jouets que l’on vous donne  Vous pouvez jouer avec les jouets que vous avez fabriqués
  • 30. 10. Loi de Demeter  Définition : soit la méthode M de l’objet O. La méthode M à la droit d’invoquer les méthodes de :  O lui-même  Des attributs / propriétés de O  Des paramètres de M  Des objets instanciés dans M var employees = someObject.GetEmployeeList(); employees.AddElementWithKey(employee.GetKey(), employee); someObject.AddToEmployees(employee);
  • 31. Conclusion & Problématique  Le refactoring n’ajoute pas de fonctionnalité, ne corrige pas de bugs  Comment vendre du temps d’improductivité à votre entreprise ? Source : http://dilbert.com/strips/comic/2007-11-26/
  • 32. Conclusion  Le refactoring est un investissement toujours payant, à vous de savoir le vendre  Le refactoring est une partie importante des méthodes agiles => Coder vite, livrer vite, refactoriser, boucler  Fonctionne de pair avec les tests unitaires
  • 33. 3. Les principes S.O.L.I.D.
  • 34. C’est quoi SOLID ?  Les pratiques SOLID permettent d’avoir des outils pour construire des logiciels de qualité  Introduites par Robert C. Martin en 2000 dans son article « Design Principles and Design Patterns »  SOLID est un acronyme de cinq lettres représentant pour chaque lettre 1 principe à respecter
  • 35. S.O.L.I.D.  Single responsibility principle  Open/closed principle  Liskov substitution principle  Interface segregation principle  Dependency inversion principle
  • 36. Single responsibility principle  Un objet doit avoir une seule responsabilité  Un objet doit avoir une seule raison de changer
  • 37. Mauvais exemple  Lit un fichier  Parse et valide les données public class Fruit { public int Id { get; set; } public string Name { get; set; } public static IEnumerable<Fruit> FruitsFromFile(string path) { // 0;Apple // 1;Orange // 2;Banana using (var reader = new StreamReader(path)) { string line; while ((line = reader.ReadLine()) != null) { var words = line.Split(';'); int id = Convert.ToInt32(words[0]); string name = words[1]; yield return new Fruit() { Id = id, Name = name }; } } }  Non testable unitairement }
  • 38. Séparer les responsabilités // Représente un fruit dans un fichier public class FruitFile { public string Id { get; set; } public string Name { get; set; } public static IEnumerable<FruitFile> FruitsFromFile(string path) { using (var reader = new StreamReader(path)) { string line; while ((line = reader.ReadLine()) != null) { var words = line.Split(';'); yield return new FruitFile() { Id = words[0], Name = words[1] }; } } } } public class Fruit { public int Id { get; set; } public string Name { get; set; } // Valide les données d'une ligne fruit public static Fruit Build(FruitFile fruitFile) { int id = Convert.ToInt32(fruitFile.Id); string name = fruitFile.Name; return new Fruit() { Id = id, Name = name }; } public static IEnumerable<Fruit> FromFile(string path) { return FruitFile.FruitsFromFile(path) .Select(fruitFile => Build(fruitFile)); } }  La validation des données devient testable unitairement
  • 39. Open/closed principle  Un objet doit être ouvert à l’extension mais fermer à la modification
  • 40. Open/closed principle  Ouvert à l’extension = Possibilité de rajouter des fonctionnalités  Fermé à la modification = Ajout des fonctionnalités sans changer le code existant  Mécanisme : Héritage, Polymorphisme, Interface (Abstraction)
  • 41. Mauvais exemple public class Rectangle { public double Width { get; set; } public double Height { get; set; } public double Area { get { return this.Width * this.Height; } } } public class Circle { public PointF Center { get; set; } public double Radius { get; set; } public double Area { get { return this.Radius * this.Radius * Math.PI; } } } public class Shapes { public double AreaOf(List<object> shapes) { double total = 0; foreach (var shape in shapes) { if (shape is Rectangle) { total += ((Rectangle)shape).Area; } else if (shape is Circle) { total += ((Circle)shape).Area; } } return total; } }  Obligation de modifier la fonction si on ajoutait un triangle
  • 42. Ajout d’un niveau d’abstraction // Abstract the Shape concept public interface IShape { double Area { get; } } public class Rectangle : IShape { public double Width { get; set; } public double Height { get; set; } public double Area { get { return this.Width * this.Height; } } } public class Circle : IShape { public PointF Center { get; set; } public double Radius { get; set; } public class Shapes { // Can run with abstract list of shapes public double AreaOf(IEnumerable<IShape> shapes) { double total = 0; foreach (var shape in shapes) { total += shape.Area; } return total; } } public double Area { get { return this.Radius * this.Radius * Math.PI; } } }  Le code est extensible pour n’importe quel forme
  • 43. Liskov substitution principle  Une classe doit pouvoir être remplacée par une instance d'une des ses sous-classes, sans modifier la validité du programme
  • 44. Liskov substitution principle  Une sous classe ne doit pas être plus contraignante que sa super classe  Ce qui peut rentrer dans la sous classe doit être moins contraignant que ce qui peut rentrer dans la super classe  Ce qui peut sortir de la sous classe doit être plus contraignant que ce qui peut sortir de la super classe
  • 45. Mauvais exemple public class Fish { } public class Duck { public virtual void Give(Fish food) { Console.WriteLine("Eating the fish"); } public class RubberDuck : Duck { public override void Give(Fish food) { throw new InvalidOperationException("Rubber Duck doesn't need fishes"); } public virtual int LegCount { get { return 2; } } } public override int LegCount { get { return 0; } } }  Le canard en plastique ne sait pas manger un poisson, il est plus contraignant sur ce qui rentre  Les canards devrait toujours avoir des pattes
  • 46. Mauvais exemple public class Test { public void Main() { var duck = new RubberDuck(); var fish = new Fish(); this.GiveFood(duck, fish); } public void GiveFood(Duck duck, Fish fish) { // we are expecting that is will never fail // unless we violate the Liskov Principle duck.Give(fish); } }  Un canard en plastique n’est pas un canard  La modélisation est incorrecte, et viole le principe de Liskov  On ne peut pas supposer un comportement si le principe de Liskov n’est pas respecté
  • 47. Interface Segregation Principle  Il vaut mieux avoir plusieurs interfaces spécifiques plutôt qu'une seule grande interface
  • 48. Mauvais exemple // Big interface, so much work public interface ICommunicate { void Send(object data); object Receive(); } public class Printer : ICommunicate { public void Send(object data) { Console.WriteLine("Printing datas..."); } // Phone is ok, can communicate both ways public class Phone : ICommunicate { public void Send(object data) { Console.WriteLine("Composing number..."); } // Printer has to define the Receive method public object Receive() { // But printer can't receive anything throw new InvalidOperationException("Printer are not receiving."); } } public object Receive() { return "Dring!"; } }
  • 49. Bon exemple // make it two interfaces instead of one public interface ISender { void Send(object data); } public interface IReceiver { void Send(object data); } public class Phone : ISender, IReceiver { public void Send(object data) { Console.WriteLine("Composing number..."); } public object Receive() { return "Dring!"; } } public class Printer : ISender { public void Send(object data) { Console.WriteLine("Printing datas..."); } }
  • 50. Dependency Inversion Principle  Les modules de haut niveau ne doivent pas dépendre des modules de bas niveau. Les deux doivent dépendre des abstractions
  • 51. Mauvais exemple // Low level module public class Logger { public void Log(string text) { Console.WriteLine(text); } } // High level module, depend on low level module public class DatabaseReader { public Logger Logger { get; set; } public void ReadData() { this.Logger.Log("Reading datas..."); } }
  • 52. Bon exemple // Abstraction public interface ILogger { void Log(string text); } // Low level modules, depend on abstraction public class ConsoleLogger : ILogger { public void Log(string text) { Console.WriteLine(text); } } // Low level modules, depend on abstraction public class FileLogger : ILogger { private readonly string _path; public FileLogger(string path) { this._path = path; } public void Log(string text) { using (var file = new StreamWriter(this._path)) { file.WriteLine(text); } } } // High level module, depend on abstraction public class DatabaseReader { public ILogger Logger { get; set; } public void ReadData() { this.Logger.Log("Reading datas..."); } }
  • 53. Conclusion  Appliquer ces principes ne garantissent pas un code sans faille, mais au moins un meilleur code  Il faut savoir pondérer ces bonnes pratiques lorsque les délais sont courts et les résultats pressants  Les définitions des principes sont simples, mais leurs mises en place complexe sur des problèmes réels
  • 54. 4. Initiation à la programmation fonctionnelle
  • 55. Historique  Programmation procédurale : Fortran, C, Basic…  A base de fonction qui s’appelle les unes les autres  Ensemble d’étape à exécuter pour arriver au résultat  Programmation orientée objet : C++, Java, C#  Définition d’un ensemble d’objet interagissant entre eux  Un objet est définit par ses états (variables) et ses comportements (méthodes)  Grande mode à partir des années 80, adopté en masse par les entreprises dans les années 90
  • 56. Historique  Aujourd’hui : le marché est toujours dominé par la programmation orienté objet, et les langages procéduraux gardent une bonne place Source : http://www.tiobe.com
  • 57. Historique de la programmation fonctionnelle  Programmation fonctionnelle : Lisp (1958), puis Scheme (1975), Haskell (1987), ou récemment F# (2002) et LINQ (2007)  N’a jamais réussi à pénétrer le marché malgré son ancienneté  Peu enseigné, peu pratiqué, peu utilisé
  • 58. A quoi ça sert alors ?  Simple à écrire, condensé  Puissant  Pas d’effet de bords par nature  Les principes de la programmation fonctionnelle sont applicables à la programmation orienté objet  Rend toute fonction parallélisable  Rend possible la mise en cache de manière automatique
  • 59. Paradigmes  Aucun état n’est modifiable, on parle d’Immutabilité  Un objet est instancié une fois, puis ne peux plus jamais être modifié  Les fonctions sont Pures, pas d’effet de bords = aucune modification d’état  Une fonction pure est une fonction qui ne modifie aucun état, et qui retourne une seule valeur  La valeur retournée est toujours la même pour les mêmes arguments d’entrée. Contrexemple : Date date = new Date(); // Impur
  • 60. Immutabilité  Sur des objets, l’initialisation passe par le constructeur public class ImmutablePoint { private readonly double _x; public double X { get { return _x; } } private readonly double _y; public double Y { get { return _y; } } public ImmutablePoint(double x, double y) { this._x = x; this._y = y; } }
  • 61. Immutabilité  Sur des conteneurs de données, chaque ajout retourne une nouvelle instance du conteneur var empty = new ImmutableList<double>(); var onlyTwo = empty.Add(2); var twoAndThree = onlyTwo.Add(3);
  • 62. Avantage de l’immutabilité  Les variables ne pourront jamais être modifié par un code tiers public void EvilCode(List<int> ints) { ints.Clear(); } var primes = new List<int>() { 2, 3, 5, 7}; EvilCode(primes); // ergh, primes is empty!
  • 63. Avantage de l’immutabilité  La programmation multi thread est simplifiée  Pas de Lock, Mutex, et autres joyeusetés  Les accès aux données sont automatiquement en lecture seule
  • 64. Exemple : un tas immutable public interface IStack<T> : IEnumerable<T> { IStack<T> Push(T value); IStack<T> Pop(); T Peek(); bool IsEmpty { get; } }
  • 65. Exemple : un tas immutable public sealed class Stack<T> : IStack<T> { private sealed class EmptyStack : IStack<T> { public bool IsEmpty { get { return true; } } public T Peek() { throw new Exception("Empty stack"); } public IStack<T> Push(T value) { return new Stack<T>(value, this); } public IStack<T> Pop() { throw new Exception("Empty stack"); } public IEnumerator<T> GetEnumerator() { yield break; } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } } private static readonly EmptyStack empty = new EmptyStack(); public static IStack<T> Empty { get { return empty; } } private readonly T head; private readonly IStack<T> tail; private Stack(T head, IStack<T> tail) { this.head = head; this.tail = tail; } public bool IsEmpty { get { return false; } } public T Peek() { return head; } public IStack<T> Pop() { return tail; } public IStack<T> Push(T value) { return new Stack<T>(value, this); } public IEnumerator<T> GetEnumerator() { for (IStack<T> stack = this; !stack.IsEmpty; stack = stack.Pop()) yield return stack.Peek(); } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } }
  • 66. Exemple : un tas immutable IStack<int> IStack<int> IStack<int> IStack<int> s1 s2 s3 s4 = = = = Stack<int>.Empty; s1.Push(10); s2.Push(20); s2.Push(30); // shares its tail with s3. Source : http://blogs.msdn.com/b/ericlippert/archive/2007/12/04/immutability-in-c-parttwo-a-simple-immutable-stack.aspx
  • 67. LINQ : Application au monde réel  LINQ arrive en 2007 avec le Framework .NET 3.5  Ensemble de fonctions inspiré de la programmation fonctionnelle qui agit sur des types IEnumerable (basiquement, des List)
  • 68. Un peu de LINQ : filtrer les éléments d’une liste  Avant  Après public List<int> MutableEvens(List<int> ints) { var evens = new List<int>(); foreach (var item in ints) { if (item % 2 == 0) { // mutation of the list evens.Add(item); } } return evens; } public List<int> ImmutableEvens(List<int> ints) { return ints.Where(i => i % 2 == 0).ToList(); }  Aucune mutation, sans effet de bords
  • 69. Un peu de LINQ : sélectionner une propriété  Avant  Après public List<int> MutableGetXs(List<Point> points) { var xs = new List<int>(); foreach (var point in points) { xs.Add(point.X); } return xs; } public List<int> ImmutableGetXs(List<Point> points) { return points.Select(p => p.X).ToList(); }
  • 70. Exercice  Refactoriser le code suivant pour le rendre immutable public class MyPoint { public double X { get; set; } public double Y { get; set; } public static void Translate(List<MyPoint> points, double dx, double dy) { foreach (var point in points) { point.X += dx; point.Y += dy; } } public override bool Equals(object obj) { var point = (MyPoint)obj; return point.X == this.X && point.Y == this.Y; } } [TestClass] public class MyPointTests { [TestMethod] public void TestTranslate() { var points = new List<MyPoint>() { new MyPoint() { X = 1, Y = 2 }, new MyPoint() { X = -1, Y = 0 } }; MyPoint.Translate(points, 1, 2); var expected = new List<MyPoint>() { new MyPoint() { X = 2, Y = 4 }, new MyPoint() { X = 0, Y = 2 } }; CollectionAssert.AreEqual(expected, points); } }
  • 71. Correction public class MyPoint { private readonly double _x; public double X { get { return _x; } } private readonly double _y; public double Y { get { return _y; } } public MyPoint(double x, double y) { this._x = x; this._y = y; } [TestClass] public class MyPointTests { [TestMethod] public void TestTranslate() { var points = new List<MyPoint>() { new MyPoint(1, 2), new MyPoint(-1, 0) }; var actual = MyPoint.Translate(points, 1, 2); var expected = new List<MyPoint>() { new MyPoint(2, 4), new MyPoint(0, 2) }; public static List<MyPoint> Translate(List<MyPoint> points, double dx, double dy) { return points.Select(p => new MyPoint(p.X + dx, p.Y + dy)).ToList(); } CollectionAssert.AreEqual(expected, actual); } public override bool Equals(object obj) { var point = (MyPoint)obj; return point.X == this.X && point.Y == this.Y; } } }
  • 72. Conclusion  Les concepts de pureté et d’immutabilité proviennent de la programmation fonctionnelle  Concepts puissants qui empêchent beaucoup d’erreurs et d’effet de bords  Demande des ajustements dans la façon de coder, et dans l’approche des problèmes  Ces concepts sont applicables dans tous les langages, objets ou procéduraux
  • 73. 5. Analyse statique L’analyse du code par des systèmes tiers
  • 74. La revue du code  Via des personnes : camarade, collègues, forums  Extreme Programming (XP) pratique le Pair programming : deux paires d'yeux valent mieux qu'une. Se passe pendant l’écriture, couteuse en ressource humaine  Code review : Se passe à postériori de l’écriture, moins couteuse  http://www.developpez.net/forums/; http://stackoverflow.com/; http://codereview.stackexchange.com/  Via des logiciels  ReSharper, NDepend, Coverity, etc.  http://en.wikipedia.org/wiki/List_of_tools_for_static_code_ analysis
  • 75. Un exemple  Capture d’écran d’un rapport NDepend
  • 76. Purity – Immutability – Side-Effects  Capture d’écran d’un rapport NDepend
  • 77. Les outils d’analyse statique  Analyse du code basé sur un ensemble de règles  Propose des avertissements dans les domaines : convention de nommage, design, architecture, code mort, etc.  Permet la modification et l’ajout de nouvelles règles  Disponible dans tout les langages, du gratuit au plus cher
  • 78. Programmation par contrat  Permet de définir des pré conditions, des post conditions et des invariants pour chaque fonction  Provient du langage Eiffel (1986) qui le supporte nativement  Supporté à base de plugin dans Visual Studio (Code Contracts) de manière statique  Plusieurs implémentations existe dans les autres langages, analyse dynamique uniquement  Java : Cofoja, SpringContracts  PHP : Praspel  CF http://en.wikipedia.org/wiki/Design_by_contract
  • 79. Code Contracts  Vérification statique à base de Warning  Vérification dynamique = lancement d’Exception  Générateur de documentation
  • 80. Exemple Code Contracts public class Test { private object _value2 = ""; public object TestMethod(object value, object value2) { Contract.Requires(value != null); // Static Warning && Runtime Exception en entrée Contract.Ensures(Contract.Result<object>() != null); // Static Warning && Runtime Exception en sortie this._value2 = value2; return null; // Static Warning } [ContractInvariantMethod] private void ObjectInvariant() { Contract.Invariant(this._value2 != null); // Static Warning && Runtime Exception en sortie } } static void Main(string[] args) { var test = new Test(); test.TestMethod(null, null); // Static Warning }
  • 81. Qualité logicielle Conclusion  Avoir en tête les fonctionnalités demandées, c’est bien  Avoir en tête la qualité et les fonctionnalités, c’est mieux  Des efforts aujourd’hui pour des effets demain  La qualité en informatique est comme la qualité en général, un investissement à long terme  La qualité demande du temps. « Vite fait bien fait » n’existe pas, fast code = dirty code
  • 82. Bibliographie  Code Complete de Steve McConnell  Refactoring: Improving the Design of Existing Code de Martin Fowler  Learn You a Haskell for Great Good!: A Beginner's Guide de Miran Lipovaca  Clean Code: A Handbook of Agile Software Craftsmanship de Robert C. Martin