/Let q(x) be a property provable about objects of x of type T. Then q(y) should be provable for objects y of type S where S is a subtype of T./
Les classes filles doivent pouvoir être substituées par leur classe mère :
* Pour une classe B, fille de A, il doit être possible de passer une instance de B à toute méthode s'attendant à avoir une instance de A, sans disfonctionnement.
#+BEGIN_SRC python :results output
classRectangle:
def__init__(self,width,height):
self._width=width
self._height=height
@property
defwidth(self):
returnself._width
@width.setter
defwidth(self,width):
self._width=width
@property
defheight(self):
returnself._height
@height.setter
defheight(self,height):
self._height=height
defget_area(self):
returnself._width*self._height
classSquare(Rectangle):
def__init__(self,size):
super().__init__(size,size)
@Rectangle.width.setter
defwidth(self,size):
self._width=size
self._height=size
@Rectangle.height.setter
defheight(self,size):
self._width=size
self._height=size
deftest_get_area(rectangle):
width=rectangle.width
rectangle.height=10
print(f'Expected area of {10*width}, got {rectangle.get_area()}')
rectangle=Rectangle(2,3)
test_get_area(rectangle)
square=Square(2)
square.width=5
test_get_area(square)
#+END_SRC
#+RESULTS:
: Expected area of 20, got 20
: Expected area of 50, got 100
La classe ~Square~ ne respecte pas le principe car le comportement de la méthode ~get_area~ diffère selon l'instance de
classe passée en paramètre.
** Principe de ségrégation d'interface (Interface segregation principle)
/A client should never be forced to implement an interface that it doesn’t use, or clients shouldn’t be forced to depend on methods they do not use./
Il s'agit d'un principe de séparation des interfaces : plusieurs interfaces spécifiques sont meilleures qu'une unique
générale. Ainsi, seules les méthodes nécessaires sont implémentées et non l'intégralité de celles définies par
l'interface générique.
Exemple d'implémentation ne respectant pas le principe : l'interface ~ParkingLot~ englobe le stationnement
ainsi que le paiement. Quid de son implémentation pour le cas d'un parking gratuit ?
L'ideal serait d'isoler la partie paiement dans une interface dédiée.
#+BEGIN_SRC python :results output
fromabcimportabstractmethod
classCar:
...
classParkingLot:
@abstractmethod
defpark_car(self):
# Decrease empty spot count by 1
...
@abstractmethod
defunpark_car(self):
# Increase empty spot count by 1
...
@abstractmethod
defget_capacity(self):
# Return car capacity
...
@abstractmethod
defcalculate_fee(self,car):
# Return the price based on the number of hours
...
@abstractmethod
defdo_payment(self,car):
# Do the payment process for the computed fee
...
classFreeParking(ParkingLot):
defpark_car(self):
...
defunpark_car(self):
...
defget_capacity(self):
...
defcalculate_fee(self,car):
# Unused method here... the parking is free.
...
defdo_payment(self,car):
# Unused method here... the parking is free.
...
#+END_SRC
** Principe d'inversion de dépendence (Dependency inversion principle)
/Entities must depend on abstractions, not on concretions. It states that the high-level module must not depend on the
low-level module, but they should depend on abstractions./
Les classes devraient être baséees sur des interfaces ou des classes abstraites plutôt que des classes concrètes,
#+BEGIN_SRC python :results output
classSqlConnection:
defconnect(self):
...
classPasswordReminder:
def__init__(self,connection:SqlConnection)->None:
...
#+END_SRC
La classe ~PasswordReminder~ ne doit pas avoir de couplage fort avec la méthode employée pour obtenir le mot de
passe. L'usage d'une interface permettrait d'abstraire la méthode de collecte.
#+BEGIN_SRC python :results outputs
fromabcimportabstractmethod
classConnection:
@abstractmethod
defconnect(self):
...
classSqlConnection(Connection):
defconnect(self):
...
classPasswordReminder:
def__init__(self,connection:Connection)->None:
...
#+END_SRC
* Références
* [[https://fi.ort.edu.uy/innovaportal/file/2032/1/design_principles.pdf][Uncle bob design principes]]
* [[https://www.freecodecamp.org/news/solid-principles-explained-in-plain-english/][SOLID principes explained in plain english - freecodecamp.org]]
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.