C'è nessun consenso su cosa distingue esattamente la programmazione orientata agli oggetti.
Storicamente, OOP è stato dapprima "scoperto" nel contesto delle simulazioni, in cui gli oggetti rappresentavano letteralmente oggetti e metodi fisici su questi oggetti rappresentavano eventi esterni a cui gli oggetti possono reagire. Il consenso generale è che questo non è un buon modo per scrivere software, ma che i principi sottostanti possono essere molto preziosi.
Un problema con la modellazione di oggetti fisici è che ciò induce in errore il design a includere relazioni irrilevanti tra oggetti e proprietà irrilevanti degli oggetti. Inoltre, spesso è più utile modellare concetti astratti anziché oggetti fisici.
Una visione più moderna non vede OOP come una tecnica per tradurre i modelli in codice, ma vede l'orientamento agli oggetti come un modo per risolvere vari problemi attraverso il polimorfismo , principalmente l'ereditarietà dell'interfaccia.
Questo di solito è un approccio dal basso verso l'alto: ho cose diverse che si comportano diversamente, ma voglio usarle come se fossero lo stesso tipo di cosa. Senza OOP, devo esaminare ogni cosa per scoprire di cosa si tratta, quindi eseguire il comportamento corretto.
Invece, posso definire un'interfaccia che descriva come voglio usarli. Quindi renderò le mie cose esistenti conformi a questa interfaccia, sia se ereditano l'interfaccia o se creo un adattatore tra l'interfaccia e una cosa specifica. Ora posso dire le cose cosa fare e possono eseguire il loro comportamento individuale senza che io conosca il loro vero tipo, perché sono conformi all'interfaccia.
Si scopre che l'OOP è un modo eccellente per ottenere modularità ed estensibilità. Dipendendo solo dalle interfacce invece che dai tipi concreti, posso sostituire le implementazioni senza ulteriori modifiche al sistema (spesso attraverso un meccanismo di "dipendenza dall'iniezione"). Una conseguenza è che i sistemi orientati agli oggetti sono più facili da testare in isolamento rispetto ai sistemi procedurali, perché posso facilmente sostituire le dipendenze reali con stub o oggetti fittizi.
Non tutti i sistemi software richiedono questo tipo di flessibilità. Molti problemi si adattano molto bene ai modelli non polimorfici. Molto spesso, un class
non viene usato perché vogliamo fare OOP, ma perché questo è l'unico meccanismo nel linguaggio per implementare tipi di record . La maggior parte delle chiamate di metodo instance.Method()
non sono polimorfiche, ma solo una comoda abbreviazione di ciò che è effettivamente una funzione statica Class.Method(instance)
.
Oltre ai "Modelli OOP nel mondo reale" e "OOP utilizza tecniche polimorfiche", esistono anche altre interpretazioni OOP:
- OOP è definito da Ereditarietà e incapsulamento (spesso insegnato in introduzioni alla programmazione, ma manca il punto)
- Oggetti = Dati + Comportamento
- Gli oggetti usano aprire la ricorsione (B. Pierce)
- I sistemi orientati agli oggetti sono SOLID (Robert C. Martin)
- Gli oggetti comunicano attraverso il passaggio dei messaggi (Alan Kay)