SlideShare une entreprise Scribd logo
1  sur  50
Principes pour Clean Code
Mohamed El yaakoubi
1
Définition
• SOLID est un acronyme qui désigne les 5 premiers principes de la
programmation orientée objet décrit par Robert Cecil Martin (Uncle
Bob)
• Il n’existe pas de hiérarchie dans ces principes
• Dans la pratique ces principes sont très imbriqués
2
Avant de commencer
• SOLID s’articule au cœur d’une architecture orienté objet,
• On peut considérer ces principes comme un « art de faire »,
de bonnes pratiques
• « Principe », pas pattern. Si SOLID va nous dire ce qu’il faudrait faire,
les patterns vont nous dire comment le faire
• Le pragmatisme doit rester maitre, une architecture trop complexe
peut en réalité nuire à ce pourquoi SOLID existe : la maintenabilité
3
5 principes
• SRP : Single Responsibility Principle
Une classe doit avoir une et une seule responsabilité
• OCP : Open/Close Principle
Une entité doit être ouverte aux extensions et fermée aux modifications
• LSP : Liskov Substitution Principle
Les sous-types doivent être interchangeables par leurs types de base
• ISP : Interface Segregation Principle
Un client ne doit pas être forcé de dépendre de méthodes qu’il n’utilise pas
• DIP : Dependency Inversion Principle
Il faut dépendre des abstractions, pas des implémentations
4
Single Responsibility Principle
SRP – La responsabilisation de classes
5
• Importer des données d'un fichier CSV dans une base de données.
SRP : Single Responsibility Principle
• Quel est le problème avec cette conception ?
• Il y a 2 responsabilités donc 2 raisons de changer.
1. Lire le fichier CSV sous forme d'enregistrements.
2. Stocker les enregistrements dans la base de données.
Exemple
6
public class EmployeeService{
private String getname(){
//implementation
}
private double getIncome(){
//implementation
}
private Date getDateOfJoining(){
//implementation
}
public boolean isPromotionDueThisYear(){
//promotion logic implementation
}
public Double calcIncomeTaxForCurrentYear(){
//income tax logic implementation
}
}
La classe EmployeeService semble
logiquement correcte.
• Il récupère tous les attributs d'employé
tels que : nom, âge et dateOfJoining.
• Il vous indique même si l'employé est
éligible à une promotion cette année.
• Il calcule l'impôt sur le revenu qu'il doit
payer pour l'année.
SRP – Exemple
7
La logique de déterminer si l'employé est éligible à avoir une promotion cette
année n'est en réalité pas une responsabilité qui appartient à l'employé. Le
service RH de l’entreprise assume cette responsabilité en fonction des
politiques RH de l’entreprise qui peuvent changer chaque années.
Lors de tout changement de ces politiques RH, la classe EmployeeService devra
être mise à jour car elle est actuellement responsable de la détermination des
promotions.
SRP – Exemple
8
De même, le calcul de l'impôt sur le revenu n'est pas une responsabilité de
l'employé. Il est de la responsabilité du service financier de s’occuper de la
structure fiscale actuelle qui peut être mise à jour chaque année.
Si la classe d'employé service détient la responsabilité du calcul de l'impôt
sur le revenu, chaque fois que la structure / les calculs fiscaux changent, la
classe d'employé devra être modifiée.
Enfin, la classe des employés devrait avoir la responsabilité unique de
maintenir les attributs de base d'un employé.
SRP – Exemple
9
Nous pouvons déplacer la logique de détermination de promotion de la classe
Employee vers une autre classe HRPromotions :
public class HRPromotions{
public boolean isPromotionDueThisYear(Employee emp){
//promotion logic implementation using the employee information
passed
}
}
De même, déplaçons la logique de calcul de l'impôt sur le revenu de la classe
Employee vers la classe FinITCalculations -
public class FinITCalculations{
public Double calcIncomeTaxForCurrentYear(Employee emp){
//income tax logic implementation using the employee information passed
}
}
SRP – Exemple
10
SRP : Single Responsibility Principle
L’idée est que si une responsabilité évolue, alors on ne risque pas de
casser les autres.
• Le code devient plus compréhensible car découpé en
responsabilité
• facile à tester.
• plus facile à étendre.
11
La cohésion recommande de placer un ensemble des éléments (composants,
classes, méthodes) ayant des rôles similaires ou dédiés à une même problématique.
La cohésion d’une classe recommande de placer un ensemble d’attributs et de
méthodes ayant des rôles similaires ou dédiés à une même responsabilité.
Cohésion
Mesurer la cohésion
Soient Vi des variables et Mi des méthodes
12
LCOM (Lack of Cohesion in Methods)
Considérons une classe C avec les méthodes M1, M2… Mn.
Soit {Ii} = ensemble de variables d'instance utilisées par la méthode Mi.
Il existe n ensembles de ce type {I1},… {In}.
LCOM = le nombre d'ensembles disjoints formés par l'intersection des n
ensembles.
13
Open/Closed Principle
OCP – LA MODIFICATION PAISIBLE
14
OCP : Open/Closed Principle
• Une classe doit être ouverte à l'extension, mais fermée à la modification
• Sauf pour la correction de bug, l’idée est de ne jamais modifier un code déjà
existant surtout s’il a déjà été testé et approuvé.
• Ce principe s’applique pour structurer notre code afin de nous procurer l'un des
plus grands avantages de la programmation orientée objet : la réutilisation et la
maintenabilité.
• Faire bon usage de l’abstraction et du polymorphisme afin d’étendre un
comportement sans le modifier (Decorator, Factory).
15
OCP : Open/Close Principle
bon usage du polymorphisme
OCP
16
• La composition avec le pattern Strategy répond aussi à ce principe
OCP : Open/Close Principle
bon usage de l’abstraction
17
class Circle {
public void paint() {
System.out.println("A Circle");
}
}
class Square {
public void display() {
System.out.println("A Square");
}
}
OCP : Open/Close Principle
Exemple
18
class Drawing {
private List shapes;
public Drawing() {
shapes = new ArrayList();
}
protected boolean is_shape(Object s) {
return s instanceof Circle || s instanceof Square;
}
@SuppressWarnings("unchecked")
final public void add(Object s) {
if (is_shape())
shapes.add(s);
else
throw new IllegalArgumentException("Unknow Shape");
}
public void drawShape(Object s) {
if (s instanceof Circle)
((Circle) s).paint();
else if (s instanceof Square)
((Square) s).display();
}
final public void drawAllShapes() {
for (Object o : shapes)
drawShape(o);
}
} 19
public class DrawAllShapes {
static public void main(String... argv) {
Drawing myDrawing = new Drawing();
myDrawing.add(new Circle());
myDrawing.add(new Square());
myDrawing.add(new Circle());
myDrawing.add(new Square());
myDrawing.add(new Circle());
myDrawing.drawAllShapes();
}
}
20
public abstract class Shape {
public abstract void draw();
}
class Circle extends Shape {
public void draw() {
System.out.println("A Circle");
}
}
class Square extends Shape {
public void draw() {
System.out.println("A Square");
}
}
21
Code Refractoring
class Drawing {
private List<Shape> shapes;
public Drawing() {
shapes = new ArrayList<Shape>();
}
final public void add(Shape s) {
shapes.add(s);
}
final public void drawAllShapes() {
for (Shape s: shapes)
s.draw();
}
}
22
Liskov Substitution Principle
LSP – Réconciliation des descendants
23
Barbara Liskov
LSP : Liskov Substitution Principle
• Le principe LSP stipule que les objets d'une superclasse doivent être remplaçables
par des objets de ses sous-classes sans interrompre l'application.
• Les classes enfants ne doivent jamais briser les définitions de type de classe
parente
Si S est un sous-type du type T
Si φ(x) est une propriété démontrable pour tout objet x
de type T, alors φ(y) est vraie pour tout objet y de type S.
24
LSP : Liskov Substitution Principle
LSP
class Bird {
public void fly(){}
public void eat(){}
}
class Crow extends Bird {}
class Ostrich extends Bird{
fly(){
throw new UnsupportedOperationException();
}
}
public BirdTest{
public static void main(String[] args){
List<Bird> birdList = new ArrayList<Bird>();
birdList.add(new Bird());
birdList.add(new Crow());
birdList.add(new Ostrich());
letTheBirdsFly ( birdList );
}
static void letTheBirdsFly ( List<Bird> birdList ){
for ( Bird b : birdList ) {
b.fly();
}
}
}
Ne pas penser « tous les oiseaux volent sauf
l’autruche » mais plutôt
« tous les oiseaux ne volent pas, l’autruche en est un »
25
class Rectangle
{
protected int width;
protected int height;
public void setWidth(int width)
{ this.width = width }
public void setHeight(int height)
{ this.height = height; }
public int area()
{ return width * height; }
//getters
}
Un carré est un rectangle ?!!
LSP : Liskov Substitution Principle
26
class Square extends Rectangle
{
public void setWidth(int width)
{
this.width = width;
this.height = width;
}
public void setHeight(int height)
{
this.width = height;
this.height = height;
}
}
LSP : Liskov Substitution Principle
27
class LiskovSubstitutionPrincipleViolated
{
public static void main(String args[])
{
Rectangle r = new Rectangle();
r.setWidth(5);
r.setHeight(10);
System.out.println(r.area());
}
}
LSP : Liskov Substitution Principle
new Square();
28
Pour obtenir une solution compatible LSP, nous créons des frères Rectangle et Square.
Nous introduisons l'interface Shape pour regrouper les méthodes courantes.
LSP : Liskov Substitution Principle
29
30
Preconditions et Postconditions
Précondition : Une condition préalable d'une classe est une règle qui doit être en place
avant qu'une action puisse être entreprise.
Par exemple, avant d'appeler une méthode qui lit à partir d'une base de données, vous
devrez peut-être satisfaire la condition préalable que la connexion à la base de données
est ouverte.
Poscondition : Les postconditions décrivent l'état des objets après la fin d'un processus.
Par exemple, on peut supposer que la connexion à la base de données est fermée après
l'exécution d'une instruction SQL.
Le LSP stipule que les préconditions d'une classe de base ne doivent pas
être renforcées par une sous-classe et que les postconditions ne peuvent
pas être affaiblies dans les sous-classes.
31
Preconditions
Une condition préalable doit être satisfaite avant qu'une méthode puisse être exécutée.
Regardons un exemple de précondition concernant les valeurs des paramètres :
public class Example {
// precondition: 0 < num <= 5
public void doSomeThing (int num) {
if (num <= 0 || num > 5) {
throw new IllegalArgumentException("Input out of range 1-5");
}
// some logic here...
}
}
32
public class ExampleExtended extends Exemple{
@Override
// precondition: 0 < num <= 10
public void doSomeThing(int num) {
if (num <= 0 || num > 10) {
throw new IllegalArgumentException("Input out of range 1-10"); }
// some logic here...
}
}
Un sous-type peut affaiblir (mais pas renforcer) la condition préalable d'une méthode qu'il remplace.
33
Une postcondition est une condition qui doit être remplie après l'exécution d'une
méthode.
Postconditions
public class Car {
protected int speed;
// postcondition: speed must reduce
protected abstract void brake(){
//implementation
}
}
public class HybridCar extends Car {
// Some properties and other methods...
@Override
// postcondition: speed must reduce
// postcondition: charge must increase
protected void brake() {
// Apply HybridCar brake
}
}
34
Cette règle stipule que les types d'arguments de méthode de sous-type
remplacés peuvent être identiques ou plus larges que les types d'arguments de
méthode de supertype. C'est ce qu'on appelle la contravaeiance des argurments.
Règle de signature
Types d'arguments de méthode
Le type de retour de la méthode de sous-type substituée peut être plus
étroit que le type de retour de la méthode de supertype. C'est ce qu'on
appelle la covariance des types de retour. La covariance indique quand un
sous-type est accepté à la place d'un supertype.
Types d'arguments de méthode
35
public class Example{
public Number generateNumber(){
//implementation
}
// Other Methods
}
La méthode generateNumber dans Example a pour type de retour Number. Remplaçons maintenant
cette méthode en renvoyant un type Integer plus étroit :
public class ExtendedExample extends Example{
@Override public Integer generateNumber()
{
return new Integer(10);
}
// Other Methods }
Puisque Integer IS-A Number, un code client qui attend Number peut remplacer Example par
ExtendedExampe sans aucun problème.
Si la méthode surchargée dans Example devait retourner un type plus large que Number, par ex. Object,
qui peut inclure n'importe quel sous-type d'objet, par ex. un camion. Tout code client qui s'appuyait sur
le type de retour Number ne pouvait pas gérer un camion !
36
Règle de signature – Exceptions
La méthode de sous-type peut lever l’exception ou une exception dérivée (mais pas
d'exceptions plus larges ou supplémentaires) que la méthode de supertype.
Cela est compréhensible car lorsque le code client substitue un sous-type, il peut
gérer la méthode en lançant moins d'exceptions que la méthode du supertype.
Cependant, si la méthode du sous-type lève de nouvelles exceptions ou des
exception plus larges, cela casserait le code client.
Interface Segregation Principle
ISP – L’ANTI OUTIL A TOUT FAIRE
37
ISP : Interface Segregation Principle
• Un client ne doit pas être forcé de dépendre de méthodes qu’il
n’utilise pas
• Préférer plusieurs interfaces spécifiques pour chaque client plutôt
qu'une seule interface générale :
• Créer des interfaces à grains fin qui sont spécifiques au client
38
ISP : Interface Segregation Principle
LSP
Le principe de séparation des interfaces (ISP) stipule qu'aucun client ne doit être contraint
de dépendre des méthodes qu'il n'utilise pas. Imaginez une interface avec de nombreuses
méthodes dans notre base de code et que beaucoup de nos classes implémentent cette
interface, bien que seules certaines de ses méthodes soient implémentées
39
public class SmtpMessage implements IMessage
{
public IList<String> ToAddresses ;
public string MessageBody ;
public string Subject;
public bool Send()
{
//Do the real work here
return true;
}
}
public interface IMessage
{
IList<String> ToAddresses ;
string MessageBody;
string Subject;
bool Send();
// Set Get
}
ISP : Interface Segregation Principle
40
public class SmsMessage implements IMessage
{
public IList<String> ToAddresses;
public string MessageBody;
public string Subject
public bool Send()
{
//Do the real work here
return true;
}
public String getSubject() throws UnsupportedOperationException
{}
public void setSubject(String Subject){} throws UnsupportedOperationException
{}
}
ISP : Interface Segregation Principle
41
ISP : Interface Segregation Principle
public interface IMessage
{
IList<String> ToAddresses ;
string MessageBody ;
bool Send();
…
}
public interface IEmailMessage implements IMessage
{
string Subject;
IList<String> BccAddresses ;
}
42
public class SmtpMessage implements IEmailMessage
{
public IList<String> ToAddresses;
public IList<String> BccAddresses ;
public string MessageBody ;
public string Subject ;
public bool Send()
{
//Do the real work here
return true;
}
}
public class SmsMessage implements IMessage
{
public IList<String> ToAddresses ;
public string MessageBody ;
public bool Send()
{
//Do the real work here
return true;
}
}
ISP : Interface Segregation Principle
43
DIP : Dependency Inversion Principle
DIP – L’ EMERGENCE DES ABSTRACTIONS
44
• Les modules de haut niveau ne doivent pas dépendre de l’implementation de
modulesde plus bas niveau
• L'idée est que chaque point de contact entre deux modules soit
matérialisé par une abstraction
• Une abstraction se matérialise par une interface ou une classe de base qui est
aussi l’abstraction de classe plus élevé
DIP : Dependency Inversion Principle
45
public class NotifyUser {
public void Notify() {
WebConfigReader config = new WebConfigReader();
User user = config.GetUserToNotify();
DatabaseContext db = new DatabaseContext();
int userid = db.GetUserFromDatabase(user);
EmailClient eml = new EmailClient();
eml.send(userid);
}
}
Violation DIP
46
DIP : Dependency Inversion Principle
DIP
47
public class. NotifyUser
{
private IDatabaseContext _dbContextService;
private IEmailClient _emailClientService;
private IConfigReader _configReaderService;
public NotifyUser(IConfigReader reader, IEmaitCLient client, IDatabaseContext db)
{
configReaderService = reader;
emailClientService = client;
dbContextService = db;
}
public void Notify()
{
User user = _configReaderService.GetUserToNotify();
int userid = _dbContextService.GetUserFromDatabase(user);
emailClientService_send(userid);
}
}
DIP : Dependency Inversion Principle
48
Autres Principes
un principe de base du développement logiciel visant à réduire la
répétition d'informations. Le principe DRY est énoncé comme suit :
«Chaque élément de connaissance ou de logique doit avoir une
représentation unique et sans ambiguïté dans un système».
DRY : Don't Repeat Yourself
49
Conclusion
• Il est possible de ne pas appliquer tous les principes SOLID d’un coup,
il n’est pas choquant d’ajuster les choix de conception au moment où
l’on en a besoin (refactoring)
• La raison, le pragmatisme et l’expérience vont nous permettre
d’arbitrer.Avec l’expérience vous pourrez appliquer
systématiquement SOLID avec le même effort, mais probablement
pas dès le début
50

Contenu connexe

Tendances (20)

Geecon09: SOLID Design Principles
Geecon09: SOLID Design PrinciplesGeecon09: SOLID Design Principles
Geecon09: SOLID Design Principles
 
Solid principles
Solid principlesSolid principles
Solid principles
 
Solid principles
Solid principlesSolid principles
Solid principles
 
SOLID Design Principles
SOLID Design PrinciplesSOLID Design Principles
SOLID Design Principles
 
Clean code: SOLID
Clean code: SOLIDClean code: SOLID
Clean code: SOLID
 
Design patterns avec Symfony
Design patterns avec SymfonyDesign patterns avec Symfony
Design patterns avec Symfony
 
Solid Principles
Solid PrinciplesSolid Principles
Solid Principles
 
SOLID principles
SOLID principlesSOLID principles
SOLID principles
 
SOLID
SOLIDSOLID
SOLID
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
MuleSoft SAP Integration using IDocs
MuleSoft SAP Integration using IDocsMuleSoft SAP Integration using IDocs
MuleSoft SAP Integration using IDocs
 
Solid Principles
Solid PrinciplesSolid Principles
Solid Principles
 
Python SOLID
Python SOLIDPython SOLID
Python SOLID
 
Software Design Patterns in Laravel by Phill Sparks
Software Design Patterns in Laravel by Phill SparksSoftware Design Patterns in Laravel by Phill Sparks
Software Design Patterns in Laravel by Phill Sparks
 
CMDBuild Ready2Use紹介資料
CMDBuild Ready2Use紹介資料CMDBuild Ready2Use紹介資料
CMDBuild Ready2Use紹介資料
 
Java spring framework
Java spring frameworkJava spring framework
Java spring framework
 
Spring User Guide
Spring User GuideSpring User Guide
Spring User Guide
 
WPF MVVM Review
WPF MVVM ReviewWPF MVVM Review
WPF MVVM Review
 
Hexagonal architecture for java applications
Hexagonal architecture for java applicationsHexagonal architecture for java applications
Hexagonal architecture for java applications
 

Similaire à SOLID _Principles.pptx

System c eniso_jan_fev_07
System c eniso_jan_fev_07System c eniso_jan_fev_07
System c eniso_jan_fev_07haythem_2015
 
Design Patterns Java
Design Patterns JavaDesign Patterns Java
Design Patterns JavaVINOT Bernard
 
JAVA-UIK-CHAP6-POO HERITAGE JAVA
JAVA-UIK-CHAP6-POO HERITAGE JAVAJAVA-UIK-CHAP6-POO HERITAGE JAVA
JAVA-UIK-CHAP6-POO HERITAGE JAVAAymen Bedwivski
 
Java uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaJava uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaAmel Morchdi
 
Java uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaJava uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaAmel Morchdi
 
Java uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaJava uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaAmel Morchdi
 
Java uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaJava uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaAmel Morchdi
 
Java uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaJava uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaAmel Morchdi
 
Python appliqué en apprentissage automatique (Applied Python in Machine Learn...
Python appliqué en apprentissage automatique (Applied Python in Machine Learn...Python appliqué en apprentissage automatique (Applied Python in Machine Learn...
Python appliqué en apprentissage automatique (Applied Python in Machine Learn...Guillaume Chevalier
 
20140123 java8 lambdas_jose-paumard-soat
20140123 java8 lambdas_jose-paumard-soat20140123 java8 lambdas_jose-paumard-soat
20140123 java8 lambdas_jose-paumard-soatSOAT
 
Design poo togo_jug_final
Design poo togo_jug_finalDesign poo togo_jug_final
Design poo togo_jug_finalDuchess France
 
Design poo togo_jug_final
Design poo togo_jug_finalDesign poo togo_jug_final
Design poo togo_jug_finalagnes_crepet
 
Chapitre 5 classes abstraites et interfaces
Chapitre 5  classes abstraites et interfacesChapitre 5  classes abstraites et interfaces
Chapitre 5 classes abstraites et interfacesAmir Souissi
 
Héritage et Polymorphisme .pdf
Héritage et Polymorphisme .pdfHéritage et Polymorphisme .pdf
Héritage et Polymorphisme .pdfAabidiHafid
 

Similaire à SOLID _Principles.pptx (20)

System c eniso_jan_fev_07
System c eniso_jan_fev_07System c eniso_jan_fev_07
System c eniso_jan_fev_07
 
Design Patterns Java
Design Patterns JavaDesign Patterns Java
Design Patterns Java
 
JAVA-UIK-CHAP6-POO HERITAGE JAVA
JAVA-UIK-CHAP6-POO HERITAGE JAVAJAVA-UIK-CHAP6-POO HERITAGE JAVA
JAVA-UIK-CHAP6-POO HERITAGE JAVA
 
Java uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaJava uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 java
 
C# 7 - Nouveautés
C# 7 - NouveautésC# 7 - Nouveautés
C# 7 - Nouveautés
 
Pensez objets avec java
Pensez objets avec javaPensez objets avec java
Pensez objets avec java
 
Memo java
Memo javaMemo java
Memo java
 
Java uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaJava uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 java
 
Java uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaJava uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 java
 
Java uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaJava uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 java
 
Java uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaJava uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 java
 
Python appliqué en apprentissage automatique (Applied Python in Machine Learn...
Python appliqué en apprentissage automatique (Applied Python in Machine Learn...Python appliqué en apprentissage automatique (Applied Python in Machine Learn...
Python appliqué en apprentissage automatique (Applied Python in Machine Learn...
 
20140123 java8 lambdas_jose-paumard-soat
20140123 java8 lambdas_jose-paumard-soat20140123 java8 lambdas_jose-paumard-soat
20140123 java8 lambdas_jose-paumard-soat
 
Cours design pattern m youssfi partie 7 facade bridge flyweight
Cours design pattern m youssfi partie 7 facade bridge flyweightCours design pattern m youssfi partie 7 facade bridge flyweight
Cours design pattern m youssfi partie 7 facade bridge flyweight
 
Qualité de code et bonnes pratiques
Qualité de code et bonnes pratiquesQualité de code et bonnes pratiques
Qualité de code et bonnes pratiques
 
Factory method
Factory method Factory method
Factory method
 
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
 
Chapitre 5 classes abstraites et interfaces
Chapitre 5  classes abstraites et interfacesChapitre 5  classes abstraites et interfaces
Chapitre 5 classes abstraites et interfaces
 
Héritage et Polymorphisme .pdf
Héritage et Polymorphisme .pdfHéritage et Polymorphisme .pdf
Héritage et Polymorphisme .pdf
 

Dernier

GAL2024 - Méthane 2030 : une démarche collective française à destination de t...
GAL2024 - Méthane 2030 : une démarche collective française à destination de t...GAL2024 - Méthane 2030 : une démarche collective française à destination de t...
GAL2024 - Méthane 2030 : une démarche collective française à destination de t...Institut de l'Elevage - Idele
 
GAL2024 - L'élevage laitier cultive la biodiversité
GAL2024 - L'élevage laitier cultive la biodiversitéGAL2024 - L'élevage laitier cultive la biodiversité
GAL2024 - L'élevage laitier cultive la biodiversitéInstitut de l'Elevage - Idele
 
comprehension de DDMRP dans le domaine de gestion
comprehension de DDMRP dans le domaine de gestioncomprehension de DDMRP dans le domaine de gestion
comprehension de DDMRP dans le domaine de gestionyakinekaidouchi1
 
GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...
GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...
GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...Institut de l'Elevage - Idele
 
JTC 2024 - Réglementation européenne BEA et Transport.pdf
JTC 2024 - Réglementation européenne BEA et Transport.pdfJTC 2024 - Réglementation européenne BEA et Transport.pdf
JTC 2024 - Réglementation européenne BEA et Transport.pdfInstitut de l'Elevage - Idele
 
JTC 2024 - SMARTER Retour sur les indicateurs de santé .pdf
JTC 2024 - SMARTER Retour sur les indicateurs de santé .pdfJTC 2024 - SMARTER Retour sur les indicateurs de santé .pdf
JTC 2024 - SMARTER Retour sur les indicateurs de santé .pdfInstitut de l'Elevage - Idele
 
GAL2024 - Décarbonation du secteur laitier : la filière s'engage
GAL2024 - Décarbonation du secteur laitier : la filière s'engageGAL2024 - Décarbonation du secteur laitier : la filière s'engage
GAL2024 - Décarbonation du secteur laitier : la filière s'engageInstitut de l'Elevage - Idele
 
Câblage, installation et paramétrage d’un réseau informatique.pdf
Câblage, installation et paramétrage d’un réseau informatique.pdfCâblage, installation et paramétrage d’un réseau informatique.pdf
Câblage, installation et paramétrage d’un réseau informatique.pdfmia884611
 
Algo II : les piles ( cours + exercices)
Algo II :  les piles ( cours + exercices)Algo II :  les piles ( cours + exercices)
Algo II : les piles ( cours + exercices)Sana REFAI
 
GAL2024 - Changements climatiques et maladies émergentes
GAL2024 - Changements climatiques et maladies émergentesGAL2024 - Changements climatiques et maladies émergentes
GAL2024 - Changements climatiques et maladies émergentesInstitut de l'Elevage - Idele
 
JTC 2024 La relance de la filière de la viande de chevreau.pdf
JTC 2024 La relance de la filière de la viande de chevreau.pdfJTC 2024 La relance de la filière de la viande de chevreau.pdf
JTC 2024 La relance de la filière de la viande de chevreau.pdfInstitut de l'Elevage - Idele
 
DISPOSITIFS-MEDICAUX-PPT.pdf............
DISPOSITIFS-MEDICAUX-PPT.pdf............DISPOSITIFS-MEDICAUX-PPT.pdf............
DISPOSITIFS-MEDICAUX-PPT.pdf............cheddadzaineb
 
GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...
GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...
GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...Institut de l'Elevage - Idele
 
WBS OBS RACI_2020-etunhjjlllllll pdf.pdf
WBS OBS RACI_2020-etunhjjlllllll pdf.pdfWBS OBS RACI_2020-etunhjjlllllll pdf.pdf
WBS OBS RACI_2020-etunhjjlllllll pdf.pdfSophie569778
 
firefly algoriyhm sac a dos step by step .pdf
firefly algoriyhm sac a dos step by step .pdffirefly algoriyhm sac a dos step by step .pdf
firefly algoriyhm sac a dos step by step .pdffirstjob4
 
conception d'un batiment r+4 comparative de defferente ariante de plancher
conception d'un  batiment  r+4 comparative de defferente ariante de plancherconception d'un  batiment  r+4 comparative de defferente ariante de plancher
conception d'un batiment r+4 comparative de defferente ariante de planchermansouriahlam
 
GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...
GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...
GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...Institut de l'Elevage - Idele
 
GAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenus
GAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenusGAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenus
GAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenusInstitut de l'Elevage - Idele
 
Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024
Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024
Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024Ville de Châteauguay
 
JTC 2024 - Leviers d’adaptation au changement climatique, qualité du lait et ...
JTC 2024 - Leviers d’adaptation au changement climatique, qualité du lait et ...JTC 2024 - Leviers d’adaptation au changement climatique, qualité du lait et ...
JTC 2024 - Leviers d’adaptation au changement climatique, qualité du lait et ...Institut de l'Elevage - Idele
 

Dernier (20)

GAL2024 - Méthane 2030 : une démarche collective française à destination de t...
GAL2024 - Méthane 2030 : une démarche collective française à destination de t...GAL2024 - Méthane 2030 : une démarche collective française à destination de t...
GAL2024 - Méthane 2030 : une démarche collective française à destination de t...
 
GAL2024 - L'élevage laitier cultive la biodiversité
GAL2024 - L'élevage laitier cultive la biodiversitéGAL2024 - L'élevage laitier cultive la biodiversité
GAL2024 - L'élevage laitier cultive la biodiversité
 
comprehension de DDMRP dans le domaine de gestion
comprehension de DDMRP dans le domaine de gestioncomprehension de DDMRP dans le domaine de gestion
comprehension de DDMRP dans le domaine de gestion
 
GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...
GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...
GAL2024 - Renouvellement des actifs : un enjeu pour la filière laitière franç...
 
JTC 2024 - Réglementation européenne BEA et Transport.pdf
JTC 2024 - Réglementation européenne BEA et Transport.pdfJTC 2024 - Réglementation européenne BEA et Transport.pdf
JTC 2024 - Réglementation européenne BEA et Transport.pdf
 
JTC 2024 - SMARTER Retour sur les indicateurs de santé .pdf
JTC 2024 - SMARTER Retour sur les indicateurs de santé .pdfJTC 2024 - SMARTER Retour sur les indicateurs de santé .pdf
JTC 2024 - SMARTER Retour sur les indicateurs de santé .pdf
 
GAL2024 - Décarbonation du secteur laitier : la filière s'engage
GAL2024 - Décarbonation du secteur laitier : la filière s'engageGAL2024 - Décarbonation du secteur laitier : la filière s'engage
GAL2024 - Décarbonation du secteur laitier : la filière s'engage
 
Câblage, installation et paramétrage d’un réseau informatique.pdf
Câblage, installation et paramétrage d’un réseau informatique.pdfCâblage, installation et paramétrage d’un réseau informatique.pdf
Câblage, installation et paramétrage d’un réseau informatique.pdf
 
Algo II : les piles ( cours + exercices)
Algo II :  les piles ( cours + exercices)Algo II :  les piles ( cours + exercices)
Algo II : les piles ( cours + exercices)
 
GAL2024 - Changements climatiques et maladies émergentes
GAL2024 - Changements climatiques et maladies émergentesGAL2024 - Changements climatiques et maladies émergentes
GAL2024 - Changements climatiques et maladies émergentes
 
JTC 2024 La relance de la filière de la viande de chevreau.pdf
JTC 2024 La relance de la filière de la viande de chevreau.pdfJTC 2024 La relance de la filière de la viande de chevreau.pdf
JTC 2024 La relance de la filière de la viande de chevreau.pdf
 
DISPOSITIFS-MEDICAUX-PPT.pdf............
DISPOSITIFS-MEDICAUX-PPT.pdf............DISPOSITIFS-MEDICAUX-PPT.pdf............
DISPOSITIFS-MEDICAUX-PPT.pdf............
 
GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...
GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...
GAL2024 - Traite des vaches laitières : au coeur des stratégies d'évolution d...
 
WBS OBS RACI_2020-etunhjjlllllll pdf.pdf
WBS OBS RACI_2020-etunhjjlllllll pdf.pdfWBS OBS RACI_2020-etunhjjlllllll pdf.pdf
WBS OBS RACI_2020-etunhjjlllllll pdf.pdf
 
firefly algoriyhm sac a dos step by step .pdf
firefly algoriyhm sac a dos step by step .pdffirefly algoriyhm sac a dos step by step .pdf
firefly algoriyhm sac a dos step by step .pdf
 
conception d'un batiment r+4 comparative de defferente ariante de plancher
conception d'un  batiment  r+4 comparative de defferente ariante de plancherconception d'un  batiment  r+4 comparative de defferente ariante de plancher
conception d'un batiment r+4 comparative de defferente ariante de plancher
 
GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...
GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...
GAL2024 - Parcellaire des fermes laitières : en enjeu de compétitivité et de ...
 
GAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenus
GAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenusGAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenus
GAL2024 - Situation laitière 2023-2024 : consommation, marchés, prix et revenus
 
Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024
Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024
Présentation_Soirée-Information_ Surverse_Thibert _30 avril 2024
 
JTC 2024 - Leviers d’adaptation au changement climatique, qualité du lait et ...
JTC 2024 - Leviers d’adaptation au changement climatique, qualité du lait et ...JTC 2024 - Leviers d’adaptation au changement climatique, qualité du lait et ...
JTC 2024 - Leviers d’adaptation au changement climatique, qualité du lait et ...
 

SOLID _Principles.pptx

  • 1. Principes pour Clean Code Mohamed El yaakoubi 1
  • 2. Définition • SOLID est un acronyme qui désigne les 5 premiers principes de la programmation orientée objet décrit par Robert Cecil Martin (Uncle Bob) • Il n’existe pas de hiérarchie dans ces principes • Dans la pratique ces principes sont très imbriqués 2
  • 3. Avant de commencer • SOLID s’articule au cœur d’une architecture orienté objet, • On peut considérer ces principes comme un « art de faire », de bonnes pratiques • « Principe », pas pattern. Si SOLID va nous dire ce qu’il faudrait faire, les patterns vont nous dire comment le faire • Le pragmatisme doit rester maitre, une architecture trop complexe peut en réalité nuire à ce pourquoi SOLID existe : la maintenabilité 3
  • 4. 5 principes • SRP : Single Responsibility Principle Une classe doit avoir une et une seule responsabilité • OCP : Open/Close Principle Une entité doit être ouverte aux extensions et fermée aux modifications • LSP : Liskov Substitution Principle Les sous-types doivent être interchangeables par leurs types de base • ISP : Interface Segregation Principle Un client ne doit pas être forcé de dépendre de méthodes qu’il n’utilise pas • DIP : Dependency Inversion Principle Il faut dépendre des abstractions, pas des implémentations 4
  • 5. Single Responsibility Principle SRP – La responsabilisation de classes 5
  • 6. • Importer des données d'un fichier CSV dans une base de données. SRP : Single Responsibility Principle • Quel est le problème avec cette conception ? • Il y a 2 responsabilités donc 2 raisons de changer. 1. Lire le fichier CSV sous forme d'enregistrements. 2. Stocker les enregistrements dans la base de données. Exemple 6
  • 7. public class EmployeeService{ private String getname(){ //implementation } private double getIncome(){ //implementation } private Date getDateOfJoining(){ //implementation } public boolean isPromotionDueThisYear(){ //promotion logic implementation } public Double calcIncomeTaxForCurrentYear(){ //income tax logic implementation } } La classe EmployeeService semble logiquement correcte. • Il récupère tous les attributs d'employé tels que : nom, âge et dateOfJoining. • Il vous indique même si l'employé est éligible à une promotion cette année. • Il calcule l'impôt sur le revenu qu'il doit payer pour l'année. SRP – Exemple 7
  • 8. La logique de déterminer si l'employé est éligible à avoir une promotion cette année n'est en réalité pas une responsabilité qui appartient à l'employé. Le service RH de l’entreprise assume cette responsabilité en fonction des politiques RH de l’entreprise qui peuvent changer chaque années. Lors de tout changement de ces politiques RH, la classe EmployeeService devra être mise à jour car elle est actuellement responsable de la détermination des promotions. SRP – Exemple 8
  • 9. De même, le calcul de l'impôt sur le revenu n'est pas une responsabilité de l'employé. Il est de la responsabilité du service financier de s’occuper de la structure fiscale actuelle qui peut être mise à jour chaque année. Si la classe d'employé service détient la responsabilité du calcul de l'impôt sur le revenu, chaque fois que la structure / les calculs fiscaux changent, la classe d'employé devra être modifiée. Enfin, la classe des employés devrait avoir la responsabilité unique de maintenir les attributs de base d'un employé. SRP – Exemple 9
  • 10. Nous pouvons déplacer la logique de détermination de promotion de la classe Employee vers une autre classe HRPromotions : public class HRPromotions{ public boolean isPromotionDueThisYear(Employee emp){ //promotion logic implementation using the employee information passed } } De même, déplaçons la logique de calcul de l'impôt sur le revenu de la classe Employee vers la classe FinITCalculations - public class FinITCalculations{ public Double calcIncomeTaxForCurrentYear(Employee emp){ //income tax logic implementation using the employee information passed } } SRP – Exemple 10
  • 11. SRP : Single Responsibility Principle L’idée est que si une responsabilité évolue, alors on ne risque pas de casser les autres. • Le code devient plus compréhensible car découpé en responsabilité • facile à tester. • plus facile à étendre. 11
  • 12. La cohésion recommande de placer un ensemble des éléments (composants, classes, méthodes) ayant des rôles similaires ou dédiés à une même problématique. La cohésion d’une classe recommande de placer un ensemble d’attributs et de méthodes ayant des rôles similaires ou dédiés à une même responsabilité. Cohésion Mesurer la cohésion Soient Vi des variables et Mi des méthodes 12
  • 13. LCOM (Lack of Cohesion in Methods) Considérons une classe C avec les méthodes M1, M2… Mn. Soit {Ii} = ensemble de variables d'instance utilisées par la méthode Mi. Il existe n ensembles de ce type {I1},… {In}. LCOM = le nombre d'ensembles disjoints formés par l'intersection des n ensembles. 13
  • 14. Open/Closed Principle OCP – LA MODIFICATION PAISIBLE 14
  • 15. OCP : Open/Closed Principle • Une classe doit être ouverte à l'extension, mais fermée à la modification • Sauf pour la correction de bug, l’idée est de ne jamais modifier un code déjà existant surtout s’il a déjà été testé et approuvé. • Ce principe s’applique pour structurer notre code afin de nous procurer l'un des plus grands avantages de la programmation orientée objet : la réutilisation et la maintenabilité. • Faire bon usage de l’abstraction et du polymorphisme afin d’étendre un comportement sans le modifier (Decorator, Factory). 15
  • 16. OCP : Open/Close Principle bon usage du polymorphisme OCP 16
  • 17. • La composition avec le pattern Strategy répond aussi à ce principe OCP : Open/Close Principle bon usage de l’abstraction 17
  • 18. class Circle { public void paint() { System.out.println("A Circle"); } } class Square { public void display() { System.out.println("A Square"); } } OCP : Open/Close Principle Exemple 18
  • 19. class Drawing { private List shapes; public Drawing() { shapes = new ArrayList(); } protected boolean is_shape(Object s) { return s instanceof Circle || s instanceof Square; } @SuppressWarnings("unchecked") final public void add(Object s) { if (is_shape()) shapes.add(s); else throw new IllegalArgumentException("Unknow Shape"); } public void drawShape(Object s) { if (s instanceof Circle) ((Circle) s).paint(); else if (s instanceof Square) ((Square) s).display(); } final public void drawAllShapes() { for (Object o : shapes) drawShape(o); } } 19
  • 20. public class DrawAllShapes { static public void main(String... argv) { Drawing myDrawing = new Drawing(); myDrawing.add(new Circle()); myDrawing.add(new Square()); myDrawing.add(new Circle()); myDrawing.add(new Square()); myDrawing.add(new Circle()); myDrawing.drawAllShapes(); } } 20
  • 21. public abstract class Shape { public abstract void draw(); } class Circle extends Shape { public void draw() { System.out.println("A Circle"); } } class Square extends Shape { public void draw() { System.out.println("A Square"); } } 21 Code Refractoring
  • 22. class Drawing { private List<Shape> shapes; public Drawing() { shapes = new ArrayList<Shape>(); } final public void add(Shape s) { shapes.add(s); } final public void drawAllShapes() { for (Shape s: shapes) s.draw(); } } 22
  • 23. Liskov Substitution Principle LSP – Réconciliation des descendants 23 Barbara Liskov
  • 24. LSP : Liskov Substitution Principle • Le principe LSP stipule que les objets d'une superclasse doivent être remplaçables par des objets de ses sous-classes sans interrompre l'application. • Les classes enfants ne doivent jamais briser les définitions de type de classe parente Si S est un sous-type du type T Si φ(x) est une propriété démontrable pour tout objet x de type T, alors φ(y) est vraie pour tout objet y de type S. 24
  • 25. LSP : Liskov Substitution Principle LSP class Bird { public void fly(){} public void eat(){} } class Crow extends Bird {} class Ostrich extends Bird{ fly(){ throw new UnsupportedOperationException(); } } public BirdTest{ public static void main(String[] args){ List<Bird> birdList = new ArrayList<Bird>(); birdList.add(new Bird()); birdList.add(new Crow()); birdList.add(new Ostrich()); letTheBirdsFly ( birdList ); } static void letTheBirdsFly ( List<Bird> birdList ){ for ( Bird b : birdList ) { b.fly(); } } } Ne pas penser « tous les oiseaux volent sauf l’autruche » mais plutôt « tous les oiseaux ne volent pas, l’autruche en est un » 25
  • 26. class Rectangle { protected int width; protected int height; public void setWidth(int width) { this.width = width } public void setHeight(int height) { this.height = height; } public int area() { return width * height; } //getters } Un carré est un rectangle ?!! LSP : Liskov Substitution Principle 26
  • 27. class Square extends Rectangle { public void setWidth(int width) { this.width = width; this.height = width; } public void setHeight(int height) { this.width = height; this.height = height; } } LSP : Liskov Substitution Principle 27
  • 28. class LiskovSubstitutionPrincipleViolated { public static void main(String args[]) { Rectangle r = new Rectangle(); r.setWidth(5); r.setHeight(10); System.out.println(r.area()); } } LSP : Liskov Substitution Principle new Square(); 28
  • 29. Pour obtenir une solution compatible LSP, nous créons des frères Rectangle et Square. Nous introduisons l'interface Shape pour regrouper les méthodes courantes. LSP : Liskov Substitution Principle 29
  • 30. 30 Preconditions et Postconditions Précondition : Une condition préalable d'une classe est une règle qui doit être en place avant qu'une action puisse être entreprise. Par exemple, avant d'appeler une méthode qui lit à partir d'une base de données, vous devrez peut-être satisfaire la condition préalable que la connexion à la base de données est ouverte. Poscondition : Les postconditions décrivent l'état des objets après la fin d'un processus. Par exemple, on peut supposer que la connexion à la base de données est fermée après l'exécution d'une instruction SQL. Le LSP stipule que les préconditions d'une classe de base ne doivent pas être renforcées par une sous-classe et que les postconditions ne peuvent pas être affaiblies dans les sous-classes.
  • 31. 31 Preconditions Une condition préalable doit être satisfaite avant qu'une méthode puisse être exécutée. Regardons un exemple de précondition concernant les valeurs des paramètres : public class Example { // precondition: 0 < num <= 5 public void doSomeThing (int num) { if (num <= 0 || num > 5) { throw new IllegalArgumentException("Input out of range 1-5"); } // some logic here... } }
  • 32. 32 public class ExampleExtended extends Exemple{ @Override // precondition: 0 < num <= 10 public void doSomeThing(int num) { if (num <= 0 || num > 10) { throw new IllegalArgumentException("Input out of range 1-10"); } // some logic here... } } Un sous-type peut affaiblir (mais pas renforcer) la condition préalable d'une méthode qu'il remplace.
  • 33. 33 Une postcondition est une condition qui doit être remplie après l'exécution d'une méthode. Postconditions public class Car { protected int speed; // postcondition: speed must reduce protected abstract void brake(){ //implementation } } public class HybridCar extends Car { // Some properties and other methods... @Override // postcondition: speed must reduce // postcondition: charge must increase protected void brake() { // Apply HybridCar brake } }
  • 34. 34 Cette règle stipule que les types d'arguments de méthode de sous-type remplacés peuvent être identiques ou plus larges que les types d'arguments de méthode de supertype. C'est ce qu'on appelle la contravaeiance des argurments. Règle de signature Types d'arguments de méthode Le type de retour de la méthode de sous-type substituée peut être plus étroit que le type de retour de la méthode de supertype. C'est ce qu'on appelle la covariance des types de retour. La covariance indique quand un sous-type est accepté à la place d'un supertype. Types d'arguments de méthode
  • 35. 35 public class Example{ public Number generateNumber(){ //implementation } // Other Methods } La méthode generateNumber dans Example a pour type de retour Number. Remplaçons maintenant cette méthode en renvoyant un type Integer plus étroit : public class ExtendedExample extends Example{ @Override public Integer generateNumber() { return new Integer(10); } // Other Methods } Puisque Integer IS-A Number, un code client qui attend Number peut remplacer Example par ExtendedExampe sans aucun problème. Si la méthode surchargée dans Example devait retourner un type plus large que Number, par ex. Object, qui peut inclure n'importe quel sous-type d'objet, par ex. un camion. Tout code client qui s'appuyait sur le type de retour Number ne pouvait pas gérer un camion !
  • 36. 36 Règle de signature – Exceptions La méthode de sous-type peut lever l’exception ou une exception dérivée (mais pas d'exceptions plus larges ou supplémentaires) que la méthode de supertype. Cela est compréhensible car lorsque le code client substitue un sous-type, il peut gérer la méthode en lançant moins d'exceptions que la méthode du supertype. Cependant, si la méthode du sous-type lève de nouvelles exceptions ou des exception plus larges, cela casserait le code client.
  • 37. Interface Segregation Principle ISP – L’ANTI OUTIL A TOUT FAIRE 37
  • 38. ISP : Interface Segregation Principle • Un client ne doit pas être forcé de dépendre de méthodes qu’il n’utilise pas • Préférer plusieurs interfaces spécifiques pour chaque client plutôt qu'une seule interface générale : • Créer des interfaces à grains fin qui sont spécifiques au client 38
  • 39. ISP : Interface Segregation Principle LSP Le principe de séparation des interfaces (ISP) stipule qu'aucun client ne doit être contraint de dépendre des méthodes qu'il n'utilise pas. Imaginez une interface avec de nombreuses méthodes dans notre base de code et que beaucoup de nos classes implémentent cette interface, bien que seules certaines de ses méthodes soient implémentées 39
  • 40. public class SmtpMessage implements IMessage { public IList<String> ToAddresses ; public string MessageBody ; public string Subject; public bool Send() { //Do the real work here return true; } } public interface IMessage { IList<String> ToAddresses ; string MessageBody; string Subject; bool Send(); // Set Get } ISP : Interface Segregation Principle 40
  • 41. public class SmsMessage implements IMessage { public IList<String> ToAddresses; public string MessageBody; public string Subject public bool Send() { //Do the real work here return true; } public String getSubject() throws UnsupportedOperationException {} public void setSubject(String Subject){} throws UnsupportedOperationException {} } ISP : Interface Segregation Principle 41
  • 42. ISP : Interface Segregation Principle public interface IMessage { IList<String> ToAddresses ; string MessageBody ; bool Send(); … } public interface IEmailMessage implements IMessage { string Subject; IList<String> BccAddresses ; } 42
  • 43. public class SmtpMessage implements IEmailMessage { public IList<String> ToAddresses; public IList<String> BccAddresses ; public string MessageBody ; public string Subject ; public bool Send() { //Do the real work here return true; } } public class SmsMessage implements IMessage { public IList<String> ToAddresses ; public string MessageBody ; public bool Send() { //Do the real work here return true; } } ISP : Interface Segregation Principle 43
  • 44. DIP : Dependency Inversion Principle DIP – L’ EMERGENCE DES ABSTRACTIONS 44
  • 45. • Les modules de haut niveau ne doivent pas dépendre de l’implementation de modulesde plus bas niveau • L'idée est que chaque point de contact entre deux modules soit matérialisé par une abstraction • Une abstraction se matérialise par une interface ou une classe de base qui est aussi l’abstraction de classe plus élevé DIP : Dependency Inversion Principle 45
  • 46. public class NotifyUser { public void Notify() { WebConfigReader config = new WebConfigReader(); User user = config.GetUserToNotify(); DatabaseContext db = new DatabaseContext(); int userid = db.GetUserFromDatabase(user); EmailClient eml = new EmailClient(); eml.send(userid); } } Violation DIP 46
  • 47. DIP : Dependency Inversion Principle DIP 47
  • 48. public class. NotifyUser { private IDatabaseContext _dbContextService; private IEmailClient _emailClientService; private IConfigReader _configReaderService; public NotifyUser(IConfigReader reader, IEmaitCLient client, IDatabaseContext db) { configReaderService = reader; emailClientService = client; dbContextService = db; } public void Notify() { User user = _configReaderService.GetUserToNotify(); int userid = _dbContextService.GetUserFromDatabase(user); emailClientService_send(userid); } } DIP : Dependency Inversion Principle 48
  • 49. Autres Principes un principe de base du développement logiciel visant à réduire la répétition d'informations. Le principe DRY est énoncé comme suit : «Chaque élément de connaissance ou de logique doit avoir une représentation unique et sans ambiguïté dans un système». DRY : Don't Repeat Yourself 49
  • 50. Conclusion • Il est possible de ne pas appliquer tous les principes SOLID d’un coup, il n’est pas choquant d’ajuster les choix de conception au moment où l’on en a besoin (refactoring) • La raison, le pragmatisme et l’expérience vont nous permettre d’arbitrer.Avec l’expérience vous pourrez appliquer systématiquement SOLID avec le même effort, mais probablement pas dès le début 50