Un singur motiv de schimbare
Principiul responsabilității unice este litera S din SOLID, cinci reguli pentru a proiecta cod care rămâne ușor de modificat. El spune: un tip trebuie să aibă o singură sarcină — și, prin urmare, un singur motiv de schimbare.
Când un tip salvează comenzi și trimite e-mailuri, el se schimbă când se schimbă stocarea și când se schimbă textul e-mailului. Două sarcini, două motive, de două ori mai mult risc să strici un lucru în timp ce îl modifici pe celălalt.
În Python regula se aplică claselor, metodelor lor și modulelor: păstrează fiecare dintre ele concentrată pe o singură sarcină.
Prea multe sarcini într-o singură clasă
Acest procesor de comenzi funcționează — dar el stochează comanda, scrie textul de confirmare și îl „trimite”, totul într-o singură metodă. Testarea separată a textului e-mailului este imposibilă, iar refolosirea părții de stocare în altă parte înseamnă să tragi după tine și codul pentru e-mail.
O clasă care face totul
process() amestecă două sarcini: stocarea și notificarea. Orice schimbare a uneia dintre ele înseamnă editarea — și retestarea — acestei aceleiași clase.
Ieșire: program Python complet
class OrderProcessor:
# process face două sarcini: stocarea ȘI notificarea.
def process(self, order, customer):
print("salvarea comenzii în stocare:", order)
print("trimiterea e-mailului către", customer + ":")
print(" Vă mulțumim! Comanda dumneavoastră", order, "a fost primită.")
p = OrderProcessor()
p.process("#1042 (2 books)", "ana@example.com")
O singură sarcină pentru fiecare clasă
Soluția: câte o clasă pentru fiecare sarcină. OrderStore doar stochează, EmailSender doar trimite. O funcție mică le coordonează.
Ieșirea este aceeași — dar acum fiecare parte poate fi modificată, testată și refolosită separat.
Împărțire în două clase
Același comportament, separat: stocarea nu știe nimic despre e-mailuri, expeditorul nu știe nimic despre stocare. Funcția process_order doar le conectează.
Ieșire: program Python complet
# OrderStore are o singură sarcină: stocarea comenzilor.
class OrderStore:
def save(self, order):
print("salvarea comenzii în stocare:", order)
# EmailSender are o singură sarcină: trimiterea e-mailurilor.
class EmailSender:
def send_confirmation(self, customer, order):
print("trimiterea e-mailului către", customer + ":")
print(" Vă mulțumim! Comanda dumneavoastră", order, "a fost primită.")
def process_order(order, customer):
store = OrderStore()
sender = EmailSender()
store.save(order)
sender.send_confirmation(customer, order)
process_order("#1042 (2 books)", "ana@example.com")
Câștigul: refolosire fără teamă
Deoarece expeditorul este o clasă separată, el trimite și o notificare de expediere — fără niciun cod de stocare implicat. Iar stocarea arhivează o comandă fără să compună vreun e-mail. Fiecare clasă a crescut în interiorul singurei sale sarcini.
Ieșire: program Python complet
class OrderStore:
def save(self, order):
print("salvarea comenzii în stocare:", order)
def archive(self, order):
print("mutarea comenzii în arhivă:", order)
class EmailSender:
def send_confirmation(self, customer, order):
print("e-mail către", customer + ": comanda", order, "a fost primită")
def send_shipping_notice(self, customer, order):
print("e-mail către", customer + ": comanda", order, "a fost expediată")
store = OrderStore()
sender = EmailSender()
# Fiecare clasă crește în interiorul propriei sarcini.
sender.send_shipping_notice("ana@example.com", "#1042")
store.archive("#0997")