<aside> <img src="notion://custom_emoji/899aa73c-260f-813c-baa9-0003a270e9e6/29eaa73c-260f-8057-931f-007a0ac7402b" alt="notion://custom_emoji/899aa73c-260f-813c-baa9-0003a270e9e6/29eaa73c-260f-8057-931f-007a0ac7402b" width="40px" />
Indice
</aside>
Nella lezione precedente abbiamo definito le classi come “stampi” per creare oggetti. Abbiamo detto che gli oggetti possiedono uno stato (i loro attributi) e un comportamento (i loro metodi).
Prendiamo un estratto del nostro Player di “Code Combat”:
class Player:
def __init__(self, name, hp, strength):
self.name = name
self.max_hp = hp
self.current_hp = hp
self.strength = strength
# ... altri attributi e metodi ...
Questo codice funziona, ma ha un problema di sicurezza e robustezza. Cosa succede se, nel nostro file main.py, un programmatore (magari noi stessi, per distrazione) scrivesse questo?
gimli = Player("Gimli", 50, 18)
# Modifica diretta degli attributi dall'esterno
gimli.current_hp = -1000
gimli.strength = 999
L’oggetto gimli è ora in uno stato incoerente (“broken” in inglese). Ha punti vita negativi e una forza spropositata, due valori che probabilmente non dovrebbero mai essere ammessi dalle regole del nostro gioco.
Il problema è che gli attributi sono pubblici: chiunque dall’esterno della classe può vederli e modificarli a piacimento, senza alcun controllo.
<aside> 💡
Raramente un software è scritto da una sola persona. In un’azienda, decine o addirittura centinaia di sviluppatori lavorano sullo stesso progetto. Nel tuo futuro lavorativo è sicuramente probabile che tu possa trovarti a usare una classe scritta da un tuo collega (e viceversa) o classi di pacchetti trovati su Internet.
Se quella classe non fosse incapsulata, potresti accidentalmente “romperla” modificando un suo attributo interno e introducendo un bug disastroso, senza nemmeno rendertene conto.
L’incapsulamento permette di scrivere codice che “protegge se stesso”. Questo modi di organizzare le classi porta a vantaggi enormi:
hp = -1000). La maggior parte dei bug viene prevenuta sul nascere.Player ha un bug (ad esempio, i suoi hp diventano negativi), grazie all’incapsulamento sai che l’errore è quasi certamente all’interno della classe Player (magari in un setter o nel metodo take_damage). Non devi cercare l’errore in migliaia di righe di codice esterno che potrebbero aver modificato quell’attributo.
</aside>L’incapsulamento (o encapsulation) è uno dei pilastri fondamentali della programmazione a oggetti. È il principio secondo cui lo stato interno di un oggetto dovrebbe essere protetto dall’accesso diretto dall’esterno.
L’idea è di nascondere i dettagli implementativi (gli attributi) rendendoli privati e di esporre solo un’interfaccia pubblica (i metodi) per interagire con l’oggetto.
Pensa a un’automobile:
Non hai bisogno di sapere come funziona il motore per guidare; ti basta usare il pedale dell’acceleratore. Anzi, è un bene che tu non possa modificare direttamente i pistoni mentre guidi: eviti di rompere la macchina!
Nella OOP, l’incapsulamento ci permette di:
hp = -1000).