SOLID
5 principes de POO
Les principes
- Single Responsibility Principle
- Open/Closed Principle
- Liskov Substitution Principle
- Interface Segregation Principle
- Dependency Inversion Principle
Single Responsibility Principle
Un module doit avoir une seule responsabilité. Une seule raison de changer.
class User {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
getFullName() {
return `<h1>Fullname: ${this.firstName} ${this.lastName}</h1>`;
}
}
Single Responsibility Principle
Un module doit avoir une seule responsabilité. Une seule raison de changer.
class User {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
getFullName() {
return this.firstName + " " + this.lastName;
}
}
function displayFullName(fullName) {
return `<h1>Fullname: ${fullName}</h1>`;
}
const user = new User("Toby", "Fox");
displayFullName(user.fullName());
Open/Closed Principle
Un module doit être ouvert aux extensions,
mais fermé aux modifications.
Possibilité d'étendre sans devoir modifier
Open/Closed Principle
class Square {
constructor(size) {
this.type = "square";
this.size = size;
}
}
class Circle {
constructor(radius) {
this.type = "circle";
this.radius;
}
}
function sumAreas(shapes) {
const areas = shapes.map(shape => {
switch (shape.type) {
case "circle":
return shape.radius * shape.radius * Math.PI;
case "square":
return shape.size * shape.size;
default:
throw new Error("Unknown shape");
}
});
return areas.reduce((sum, area) => sum + area, 0);
}
Open/Closed Principle
class Square {
constructor(size) {
this.type = "square";
this.size = size;
}
area() {
return this.size * this.size;
}
}
class Circle {
constructor(radius) {
this.type = "circle";
this.radius;
}
area() {
return this.radius * this.radius * Math.PI;
}
}
function sumAreas(shapes) {
const areas = shapes.map(shape => shape.area());
return areas.reduce((sum, area) => sum + area, 0);
}
Liskov Substitution Principle
(sympa le nom...)
Si deux classes réalise la même interface, on peut utiliser l'une ou l'autre sans casser le programme.
Si ça casse, alors elles ne devraient pas partager la même interface.
L'abstraction est incorrecte
Liskov Substitution Principle
class Rectangle {
setHeight(height) {
this.height = height;
}
setWidth(width) {
this.width = width;
}
}
class Square extends Rectangle {
setHeight(height) {
// Uh oh... :S
// Que faire ?
}
}
Interface Segregation Principle
// Interface pour des formes géométrique,
// imposée par une librairie
interface Shape {
area()
volume()
}
class Square {
area() {
this.size * this.size;
}
// En trop généralisant, on force le client
// à faire des choses incorrectes
volume() {
// ? throw error ?
}
}
Ne pas forcer le code client à implémenter une interface dont il n'a pas usage.
Dependency Inversion Principle
Les modules de haut niveau ne doivent pas dépendre des détails des modules de bas niveau.
Ils doivent dépendre d'abstractions que les modules de bas-niveau doivent satisfaire
Dependency Inversion Principle
// Déplace la voiture un peu en avant
function avancerUnPeu(voiture) {
voiture.tourneClef();
voiture.enleveFreinAMain();
voiture.appuieAccelerateur();
voiture.freine();
voiture.metFreinAMain();
voiture.tourneClef();
}
Dependency Inversion Principle
class VehiculeVoiture {
constructor(voiture) {
this.voiture = voiture;
}
allumer() {
this.voiture.tourneClef();
this.voiture.enleveFreinAMain();
}
avancer() {
this.voiture.appuieAccelerateur();
}
arreter() {
this.voiture.freine();
}
eteindre() {
this.voiture.metFreinAMain();
this.voiture.tourneClef();
}
}
// Déplace un véhicule un peu en avant
function avancerUnPeu(vehicule) {
vehicule.allumer();
vehicule.avancer();
vehicule.arreter();
vehicule.eteindre();
}
const vehicule = new VehiculeVoiture(voiture);
avancerUnPeu(vehicule);
SOLID
By Nicolas Gaborit
SOLID
Les principes de POO SOLID
- 68