SOLID to pięć zasad projektowania do budowania łatwych w utrzymaniu, elastycznych systemów OOP. Każda z nich adresuje częstą przyczynę sztywnego, kruchogo kodu.
SOLID to pięć zasad projektowania do budowania łatwych w utrzymaniu, elastycznych systemów OOP. Każda z nich adresuje częstą przyczynę sztywnego, kruchogo kodu.
| Litera | Zasada | Znaczenie w jednym zdaniu |
|---|
| S | Single Responsibility | Klasa powinna mieć jeden powód, aby się zmieniać |
| O | Open/Closed | Otwarta na rozszerzenie, zamknięta na modyfikację |
| L | Liskov Substitution | Podtypy muszą być użyteczne w miejscach, gdzie używany jest typ bazowy |
| I | Interface Segregation | Wiele małych interfejsów jest lepsze niż jeden duży |
| D | Dependency Inversion | Zależ od abstrakcji, a nie od konkretnych klas |
# Dependency Inversion: high-level code depends on an abstraction
class Notifier: # abstraction
def send(self, msg): ...
class EmailNotifier(Notifier):
def send(self, msg): print("email:", msg)
class OrderService:
def __init__(self, notifier: Notifier): # injected abstraction
self.notifier = notifier # not "new EmailNotifier()"
def place(self):
self.notifier.send("order placed") # works with ANY Notifier
OrderService nie zależy od e-maila — zamień go na SMS lub test double bez dotykania go (D). Dodanie nowego typu notifikatora nie wymaga zmian w OrderService (O).
SOLID to wskazówka, a nie prawo. Nadmierne stosowanie go — jeden interfejs na klasę, indirekcja wszędzie — prowadzi do "abstraction soup", która jest trudniejsza do śledzenia niż problem, który miała rozwiązać.
SOLID daje wspólny język diagnostyczny: recenzenci mogą nazwać dlaczego klasę trudno zmienić ("to narusza SRP") zamiast debatować na podstawie gustu.
Zastosowane z rozsądkiem, zasady zmniejszają efekty domina — zmiany pozostają lokalne, nowe funkcje rozszerzają się zamiast być przepisywane, a testy mogą zastępować fałszywki rzeczywistych zależności.