Reguły SOLID a programowanie obiektowe – część 2
Ostatnia aktualizacja 26 lipca, 2023
Zasady SOLID to akronim pięciu podstawowych założeń lub dobrych praktyk pozwalających na lepsze programowanie obiektowe. Określenie to stworzył Uncle Bob, czyli Robert C. Martin będący autorytetem, jeśli chodzi o programowanie obiektowe. W dziesiątej lekcji kursu programowania w JavaScript opowiada o nich dokładniej Mateusz Bogolubow, który notabene stworzył to szkolenie wraz z firmą No Fluff Jobs, jako jeden z serii kursów Junior IT Masterclazz.
Reguły SOLID a programowanie obiektowe
SOLID jest akronimem, który stworzył Robert C. Martin, zwany również przez niektórych Wujkiem Bobem (Uncle Bob). Ten zestaw zasad to pięć najważniejszych założeń programowania obiektowego (podane za Wikipedią):
- S – SRP – Single Responsibility Principle, czyli Zasada Jednej Odpowiedzialności – klasa powinna mieć tylko jedną odpowiedzialność (nigdy nie powinien istnieć więcej niż jeden powód do modyfikacji klasy).
- O – OCP – Open/Closed Principle – Zasada Otwarte/Zamknięte – klasy (encje) powinny być otwarte na rozszerzenia i zamknięte na modyfikacje.
- L – LSP – Liskov Substitution Principle – Zasada Podstawienia Liskov – funkcje które używają wskaźników lub referencji do klas bazowych, muszą być w stanie używać również obiektów klas dziedziczących po klasach bazowych, bez dokładnej znajomości tych obiektów.
- I – ISP – Interface Segregation Principle – Zasada Segregacji Interfejsów – wiele dedykowanych interfejsów jest lepsze niż jeden ogólny.
- D – DIP – Dependency Inversion Principle – Zasada Odwrócenia Zależności -wysokopoziomowe moduły nie powinny zależeć od modułów niskopoziomowych – zależności między nimi powinny wynikać z abstrakcji.
Sprawdź: jakie są umiejętności jutra
Kurs Junior IT Masterclazz „OOP w praktyce – czyli szachowe potyczki w JavaScript” – lekcja 10
Warto poznać ofertę kursu Junior IT Masterclazz „OOP w praktyce – czyli szachowe potyczki w JavaScript”. Prowadzi go doświadczony programista, a mianowicie Mateusz Bogolubow z Devmentor.pl.
Dziesiąta lekcja tymczasem zatytułowana jest „SOLIDne wytwarzanie oprogramowania – część 2”. Można w niej bowiem poznać zastosowanie, wspomnianych wcześniej, trzech ostatnich zasad SOLID w programowaniu obiektowym w zastosowaniach praktycznych. Są to:
- Zasada Podstawienia Liskov,
- Zasada Segregacji Interfejsów,
- Zasada Odwrócenia Zależności.
Przedstawione informacje stanowią oczywiście tylko niewielki fragment cennych wskazówek. Dlatego też warto sprawdzić wszystkie lekcje dotyczące OOP, a także inne kursy z serii Junior Masterclazz. Są one przygotowane i udostępniane przez No Fluff Jobs.
Kursy umożliwią Ci zdobycie solidnych podstaw do stawiania pierwszych kroków w branży IT. Wiedzę przekazują praktycy w swoich dziedzinach, a niektórych z nich mogł(a/e)ś już spotkać w innych kanałach komunikacji.
Zobacz: ile może zarobić Product Manager
Jak stosować zasady SOLID w Pythonie?
Poniższy kod napisany jest Pythonie i ilustruje zasady SOLID.
Single Responsibility Principle (SRP)
Klasa User
ma tylko jedną odpowiedzialność – przechowywanie informacji o użytkowniku.
class User:
def __init__(self, name, email):
self.name = name
self.email = email
Open-Closed Principle (OCP)
Klasa Greeter
jest otwarta na rozszerzenia (możemy stworzyć nową klasę, która dziedziczy po Greeter
), ale zamknięta na modyfikacje (nie musimy modyfikować klasy Greeter
, aby dodać nową funkcjonalność).
class Greeter:
def greet(self, user):
return f"Hello, {user.name}!"
class ExcitedGreeter(Greeter):
def greet(self, user):
return f"Hello, {user.name}!!!"
Liskov Substitution Principle (LSP)
Klasa ExcitedGreeter
jest podtypem klasy Greeter
i może być używana tam, gdzie używana jest klasa Greeter
, bez wpływu na poprawność programu.
def say_hello(greeter, user):
print(greeter.greet(user))
user = User("Alice", "alice@example.com")
greeter = Greeter()
excited_greeter = ExcitedGreeter()
say_hello(greeter, user) # prints "Hello, Alice!"
say_hello(excited_greeter, user) # prints "Hello, Alice!!!"
Interface Segregation Principle (ISP)
W Pythonie nie ma formalnych interfejsów, ale możemy zasymulować ten koncept, tworząc klasy bazowe z wymaganymi metodami. Poniżej EmailSender
i SmsSender
są “interfejsami”, które segregują odpowiedzialności.
class EmailSender:
def send_email(self, email, message):
pass
class SmsSender:
def send_sms(self, phone_number, message):
pass
class NotificationService:
def __init__(self, email_sender, sms_sender):
self.email_sender = email_sender
self.sms_sender = sms_sender
def send_notification(self, user, message):
self.email_sender.send_email(user.email, message)
# self.sms_sender.send_sms(user.phone_number, message)
Dependency Inversion Principle (DIP)
Klasa NotificationService
zależy od abstrakcji (EmailSender
i SmsSender
), a nie od konkretnych klas. Dzięki temu możemy łatwo zamienić sposób wysyłania powiadomień bez modyfikacji klasy NotificationService
.
class MockEmailSender(EmailSender):
def send_email(self, email, message):
print(f"Mock email sent to {email}: {message}")
class MockSmsSender(SmsSender):
def send_sms(self, phone_number, message):
print(f"Mock SMS sent to {phone_number}: {message}")
mock_email_sender = MockEmailSender()
mock_sms_sender = MockSmsSender()
notification_service = NotificationService(mock_email_sender, mock_sms_sender)
notification_service.send_notification(user, "Hello, Alice!")
Czytaj także:
2FA coraz częściej obligatoryjnym zabezpieczeniem
Unix, Linux – dla kogo są przeznaczone?
Junior developer – czym się zajmuje?