Académique Documents
Professionnel Documents
Culture Documents
2022/2023
S.O.L.I.D
OCP
Une opération à cœur ouvert n’est pas
nécessaire lorsqu’on enfile un vêtement
Principe Ouvert/Fermé
Image : http://lostechies.com/derickbailey/2009/02/11/solid-development-principles-in-motivational-pictures/
OCP décrit par Robert C Martin https://drive.google.com/file/d/0BwhCYaYDn8EgN2M5MTkwM2EtNWFkZC00ZTI3LWFjZTUtNTFhZGZiYmUzODc1/view 2
accessible depuis http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
Les principes SOLID : OCP (Principe Ouvert/fermé)
La télévision :
ouverte à l’extension,
mais fermée à la modification
dépendance
Inspiré de : http://joelabrahamsson.com/a-simple-example-of-the-openclosed-principle/ 6
Illustration du principe OCP : calcul d’aire (2/3)
Extension du calcul d’aire à une nouvelle forme …
public class AreaCalculator {
https://miro.medium.com/v2/resize:fit:1400/1*9jWIXdyr3o-EHANTpobBng.png 9
Illustration du
principe OCP :
Exemple 3
Respect OCP !
https://miro.medium.com/v2/resize:fit:1400/1*9jWIXdyr3o-EHANTpobBng.png 10
Exercice:
1. Pourquoi le code suivant ne respecte pas
le principe OCP?
2. Proposer une piste de refactoring:
representation UML + code JAVA
https://miro.medium.com/v2/resize:fit:1400/1*9jWIXdyr3o-EHANTpobBng.png 11
Exercice: solution
1. Pourquoi le code suivant ne respecte pas le
principe OCP?
https://miro.medium.com/v2/resize:fit:1400/1*9jWIXdyr3o-EHANTpobBng.png 12
Exercice: solution
2. code java:
https://miro.medium.com/v2/resize:fit:1400/1*9jWIXdyr3o-EHANTpobBng.png 13
S.O.L.I.D ISP
Où voulez-vous brancher cela ?
Image : http://lostechies.com/derickbailey/2009/02/11/solid-development-principles-in-motivational-pictures/
LSP décrit par Robert C Martin https://drive.google.com/file/d/0BwhCYaYDn8EgOTViYjJhYzMtMzYxMC00MzFjLWJjMzYtOGJiMDc5N2JkYmJi/view 14
accessible depuis http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
Retour sur un bon principe OO :
Coder avec une interface plutôt qu’une implémentation
c-a-d utiliser les interfaces comme des types
Quel type ?
Souple !
car code fonctionne avec n’importe quel classe d’Athlète !
… Mais
public class Worker implements IWorker{ public class SuperWorker implements IWorker{
public void work() { public void work() {
// ....working //.... working much more
} }
public void eat() { public void eat() {
// ...... eating in launch break //.... eating in launch break
} }
} }
17
Inspiré de : http://www.drims-academy.fr/clean-code-partie-1/ et http://www.oodesign.com/interface-segregation-principle.html
Illustration du principe ISP: Une interface commune? (2/4)
… mais la technologie évoluant, on fait intervenir des travailleurs robots,
et ces derniers n’ont pas besoin de manger.
21
Principe ISP :
Exercice: Solution
22
Principe ISP :
Exercice: Solution
23
S.O.L.I.D
LSP
Ca ressemble à un canard,
ça cancane comme un canard, mais à besoin de piles.
Vous avez surement la mauvaise abstraction.
Image : http://lostechies.com/derickbailey/2009/02/11/solid-development-principles-in-motivational-pictures/
LSP décrit par Robert C Martin https://drive.google.com/file/d/0BwhCYaYDn8EgNzAzZjA5ZmItNjU3NS00MzQ5LTkwYjMtMDJhNDU5ZTM0MTlh/view 24
accessible depuis http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
Les principes SOLID : LSP (Principe de Substition
de Liskov)
Principe de Substitution énoncé par Barbara Liskov et Jeannette Wing (1993)
Si q(x) est une propriété démontrable pour tout objet x de type T, alors
q(y) est vraie pour tout objet y de type S tel que S est un sous-type de T.
c-a-d que les sous-classes doivent pouvoir remplacer leur classe de base et
que les méthodes qui utilisent des objets d’une classe doivent pouvoir utiliser “inconsciemment”
des objets dérivés de cette classe
@Override
public void setHeight(double height) {
super.setHeight(height);
super.setWidth(height);
}
} … Et pourtant …
26
Inspiré de : http://www.drims-academy.fr/clean-code-partie-1/ et http://www.oodesign.com/liskov-s-substitution-principle.html
Illustration du principe LSP: un héritage bien nécessaire?
public class LiskovTest { (2/3)
@Test
public void shouldComputeArea() {
Rectangle rectangle = new Square();
rectangle.setWidth(5.0);
rectangle.setHeight(10.0);
assertEquals (50.0, rectangle.area(), 0.1);
}
} MAIS … Violation du « Contrat » à l’exécution :
Compilation OK ! Aire attendue : 50.0
Aire calculée : 100.0
A quoi sert un attribut
hauteur dans un carré
(height) ?
//…
28
Inspiré de : http://www.drims-academy.fr/clean-code-partie-1/ et http://www.oodesign.com/liskov-s-substitution-principle.html
Illustration du principe LSP : un héritage judicieux ?
(1/3)
Plateau conçu pour la création de jeux de stratégies autour
de batailles terrestres (2D) entre unités de combat
29
Inspiré de Analyse et Conception Orienté Objet – Tête la première
Illustration du principe LSP : un héritage judicieux ?
(2/3)
???
Avec une relation de généralisation, ???
on hérite de tout !
???
???
???
Composition
Permet d’utiliser le comportement d’une famille d’autres classes (souvent
représentée par plusieurs implémentations d’une même interface) et de
changer ce comportement pendant le fonctionnement de l’application.
Quand l’objet est détruit, tous ses comportement le sont aussi :
les comportements n’existent pas en dehors de la composition elle-même.
Agrégation
Permet d’utiliser les comportements d’une autre classe sans limiter la durée
de vie de ces comportements. Les comportements agrégés continuent à
exister même après que l’objet qui les agrège ait été détruit.
32
Inspiré de Analyse et Conception Orienté Objet – Tête la première
S.O.L.I.D
DIP
Est-ce que vous souderiez directement
un branchement électrique dans un mur ?
Image : http://lostechies.com/derickbailey/2009/02/11/solid-development-principles-in-motivational-pictures/
DIP décrit par Robert C Martin https://drive.google.com/file/d/0BwhCYaYDn8EgMjdlMWIzNGUtZTQ0NC00ZjQ5LTkwYzQtZjRhMDRlNTQ3ZGMz/view 33
accessible depuis http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
Les principes SOLID:DIP (Principe d’Invsersion
des Dépendances)
1. Les modules de haut niveau ne doivent pas
dépendre de modules de plus bas niveau.
Les deux doivent dépendre d’abstractions.
36
Inspiré de : https://www.youtube.com/watch?v=xwJPCiXnlMU et https://github.com/nphumbert/crafties-dip
Illustration du principe DIP: un cryptage bien découplé ?
La hachage du mot de passe se fait par un Provider qui permet d’effectuer le hash (3/3)
Pourquoi y-a-t-il Violation du principe ISP ?
public class UserServiceImpl implements UserService {
private final HashProvider hashProvider
private final Sha256HashProvider hashProvider;
public UserServiceImpl() { public UserServiceImpl(HashProvider hashProvider) {
hashProvider = new Sha256HashProvider();
} this.hashProvider = hashProvider;
}
@Override
public User createUser(String firstName, String password) {
String hashedPassword = hashProvider.hash(password); Injection de
return new User(firstName, hashedPassword); dépendance
}
}
Le provider de hash (considéré comme bas niveau car relatif aux détails technique)
ne respecte pas DIP
car il dépend directement d’une implémentation et non d’une abstraction !
Pour respecter DIP, comme « Les détails doivent dépendre des abstractions»,
on souhaiterait plutôt voir dépendre d’une interface HashProvider
et que public class Sha256HashProvider implements HashProvider
37
Inspiré de : https://www.youtube.com/watch?v=xwJPCiXnlMU et https://github.com/nphumbert/crafties-dip
Illustration du principe DIP: un cryptage bien découplé !!!
1. Les modules de haut niveau ne
doivent pas dépendre de modules
de plus bas niveau.
Les deux doivent dépendre
d’abstractions.
39
Inspiré de : https://www.youtube.com/watch?v=xwJPCiXnlMU et https://github.com/nphumbert/crafties-dip
Illustration du principe DIP : autre exemple …
Violation du principe DIP
… et du principe OCP !
40
Exrait de: https://scotch.io/bar-talk/s-o-l-i-d-the-first-five-principles-of-object-oriented-design
Concevoir, c’est faire des choix…
et faire des choix demande de prendre du recul et de s’interroger
Une classe doit avoir une et une seule responsabilité
SRP chaque classe a-t-elle une responsabilité qui lui est propre ?
Un client ne devrait jamais être forcé de dépendre d’une interface qu’il n’utilise pas
ISP S’il y a des interfaces, ne sont-elles trop générales ? Peuvent-elles être séparées en interfaces plus
spécifiques pour être mieux ciblées ? (tout en ne tombant pas dans l’excès d’une interface par méthode)
1. Les modules de haut niveau ne doivent pas dépendre de modules de plus bas niveau. Les deux doivent
dépendre d’abstractions.
DIP 2. Les abstractions ne doivent pas dépendre des détails. Les détails doivent dépendre des abstractions.
Y-a-t-il assez d’abstractions (interface) pour découpler correctement les modules de haut niveau des
modules de bas niveau ? Est-ce qu’on dépend des abstractions et non des implémentations?
Le fonctionnel est-il bien indépendant du technique ? 41
…et faire aussi des compromis parfois !
Le pragmatisme et l’expérience vont nous permettre d’arbitrer
sur une conception plus ou moins abstraite, plus ou moins tolérante au changement.
Extrait : https://www.slideshare.net/brain79/desing-principles-tensions-and-synergies-v30/16
A voir : https://github.com/lucaminudel/tensions_and_synergies_between_design_principles
43
Inspiré de : http://liris.cnrs.fr/laetitia.matignon/enseignements.html
Conclusion : Contribution de SOLID
aux bonnes pratiques de conception
… Ou comment concevoir des logiciels maintenables et réutilisables …