Il concetto di programmazione ad oggetti è un tema vasto e affascinante, e fino a questo momento abbiamo analizzato solo superficiali aspetti di esso. Un programmatore abituato alla programmazione procedurale potrebbe non aver ancora colto appieno i vantaggi dell’approccio orientato agli oggetti. Tra gli elementi centrali della programmazione ad oggetti, l’astrazione gioca un ruolo fondamentale: essa ci consente di descrivere in maniera essenziale una determinata realtà. Ad esempio, abbiamo utilizzato l’astrazione definendo la classe “Numeri” con gli attributi “numeroX” e “numeroY”. In aggiunta, abbiamo impiegato l’astrazione ogni volta che abbiamo realizzato uno dei metodi all’interno della classe “OperazioniSuNumeri”, come i metodi “somma” e “sottrazione”, in cui abbiamo espresso concetti ben definiti.
Possiamo affermare che l’astrazione rappresenta la base della programmazione orientata agli oggetti. Se combinata con altri elementi fondamentali, come l’incapsulamento, l’ereditarietà e il polimorfismo, contribuisce a raggiungere l’essenza della programmazione orientata agli oggetti, la quale offre la straordinaria opportunità del riuso del codice nello sviluppo di nuovi software.
Ogni software house moderna sfrutta la proprietà del riuso del codice per velocizzare il processo produttivo e facilitare l’implementazione di nuove funzionalità. La versione iniziale di un codice diventa la base su cui costruire versioni successive, le quali si limitano ad estendere le funzionalità previste in origine. Se il codice è stato scritto con attenzione, sarà possibile aggiungere funzionalità senza dover modificare il codice esistente. Negli ultimi anni, molti linguaggi web, come ad esempio il PHP—che era originariamente un linguaggio di programmazione puramente procedurale—hanno adottato un approccio orientato agli oggetti a partire dalla versione 5, al fine di poter sfruttare i benefici di cui sopra. I concetti di incapsulamento, ereditarietà e polimorfismo saranno trattati in modo approfondito nel corso della guida.
Incapsulamento
Adesso concentriamoci sul concetto di incapsulamento. Grazie a questo principio, il codice di una classe risulta più robusto, ovvero meno vulnerabile a errori causati da un uso scorretto dell’applicazione da parte degli utenti. Inoltre, l’incapsulamento facilita la manutenzione del codice, soprattutto in caso di modifiche o miglioramenti futuri. L’idea cardine dell’incapsulamento è quella di controllare l’accesso agli attributi di una classe tramite l’uso di metodi dedicati.
La prima misura da adottare è rendere gli attributi delle classi non modificabili direttamente dall’esterno, creando al contempo metodi con modificatore public per consentire l’accesso ai dati. Dal punto di vista dell’implementazione, l’utente interagirà semplicemente con il metodo per inserire un valore in un attributo di una classe, senza preoccuparsi di come questo metodo gestisca i dati. In sostanza, si offrono interfacce pubbliche agli utenti per l’accesso ai dati. Compito del programmatore sarà garantire che queste interfacce siano robuste, implementando opportuni controlli sull’input fornito dall’utente.
Nel caso in cui l’interfaccia pubblica necessiti di migliorie o controlli aggiuntivi, sarà sufficiente effettuare modifiche al codice relativo all’interfaccia, senza alterare l’esperienza dell’utente. L’utente continuerà ad utilizzare la medesima interfaccia, ignorando eventuali modifiche apportate.
Questo approccio alla programmazione trova riscontro in molte operazioni quotidiane. Per esempio, quando mettiamo in moto un’automobile, non fa alcuna differenza per il guidatore se il veicolo ha un motore a benzina o Diesel. L’interfaccia pubblica in questo caso è la fessura in cui inseriamo la chiave; starà poi a quest’interfaccia gestire l’avvio della macchina a seconda del tipo di motore.
Nella prossima lezione, esploreremo come implementare il concetto di incapsulamento dal punto di vista del codice, approfondendo le tecniche e i principi per una scrittura di codice più efficace e manutenibile.