제이온

[Oggetti] Capitolo 1. Oggetti, progettazione

Creato: 2024-04-28

Creato: 2024-04-28 13:45

Introduzione

Robert L. Glass sosteneva che la pratica precedesse la teoria. Lo sviluppo del software, in particolare, è un campo in cui la pratica è in anticipo rispetto alla teoria, e gli sviluppatori traggono il massimo vantaggio quando si sporcano le mani con codice concreto. Pertanto, metteremo da parte per un momento teoria e concetti e daremo un'occhiata a un semplice programma.


Implementare un'applicazione per la vendita di biglietti

  • Stiamo pianificando un piccolo evento per promuovere un piccolo teatro.
    • Contenuto dell'evento: inviare inviti gratuiti per assistere allo spettacolo a spettatori selezionati tramite estrazione a sorte.
  • Dobbiamo separare gli spettatori che hanno vinto l'estrazione da quelli che non hanno vinto.
    • Spettatori vincenti: scambiare l'invito con un biglietto.
    • Spettatori perdenti: acquistare il biglietto con denaro.



Qual è il problema?

Robert Martin spiega le tre funzioni che un modulo software (indipendentemente dalle dimensioni, come una classe, un pacchetto o una libreria, qualsiasi elemento che costituisca un programma) dovrebbe avere.


  • Funziona correttamente durante l'esecuzione.
  • Esiste per essere modificato.
    • Le modifiche devono essere possibili con un minimo sforzo.
  • Comunica con chi legge il codice.
    • Deve essere facile da leggere e comprendere per gli sviluppatori.


L'applicazione per la vendita di biglietti precedente soddisfa il primo vincolo, ovvero funzionare correttamente, ma non soddisfa gli obiettivi di facilità di modifica e comunicazione.


Codice inaspettato

Diamo un'occhiata al motivo per cui non soddisfa l'obiettivo della comunicazione.


  • Cosa fa il metodo enter() della classe Theater
    • Il teatro apre la borsa dello spettatore e controlla se contiene un invito.
    • Se la borsa contiene un invito, ordina al venditore di biglietti di trasferire il biglietto conservato nella biglietteria nella borsa dello spettatore.
    • Se la borsa non contiene un invito, estrae dalla borsa dello spettatore la quantità di denaro corrispondente al prezzo del biglietto, acquista il biglietto e lo inserisce nella borsa.
  • Dal punto di vista dello spettatore, deve assistere a un terzo, il teatro, che rovista nella sua borsa, prende i suoi soldi e mette un biglietto nella borsa.
  • Dal punto di vista del venditore di biglietti, deve assistere a un terzo, il teatro, che manipola senza permesso biglietti e denaro nella biglietteria.
  • Il codice comprensibile è un codice il cui comportamento non si discosta eccessivamente dalle nostre aspettative, e questo teatro non è in linea con le nostre aspettative.
    • Lo spettatore dovrebbe prendere i soldi dalla sua borsa e pagarli al venditore di biglietti per ricevere il biglietto.
    • Il venditore di biglietti dovrebbe prendere il biglietto direttamente dalla biglietteria e consegnarlo allo spettatore, ricevendo i soldi da quest'ultimo e conservandoli nella biglietteria.
  • Inoltre, per comprendere il metodo enter(), è necessario ricordare tutti i dettagli.
    • Audience ha un oggetto Bag.
    • La borsa contiene denaro e biglietti.
    • TicketSellet vende biglietti presso TicketOffice, e TicketOffice conserva denaro e biglietti.


Codice vulnerabile alle modifiche

Il metodo enter() presuppone due condizioni.

  • Lo spettatore porta sempre con sé una borsa per conservare denaro e inviti.
  • Il venditore di biglietti vende biglietti solo alla biglietteria.


E se la situazione fosse diversa?

  • Lo spettatore potrebbe non avere una borsa.
  • Lo spettatore potrebbe utilizzare una carta di credito invece di contanti.
  • Il venditore di biglietti potrebbe vendere biglietti anche al di fuori della biglietteria.


Ad esempio, per soddisfare la prima richiesta, dovremmo rimuovere l'oggetto Bag di Audience e modificare il metodo enter() della classe Theater. Questo perché la classe Theater si basa su informazioni troppo dettagliate, come il fatto che lo spettatore abbia una borsa e che il venditore di biglietti venda i biglietti solo alla biglietteria. Se anche solo uno di questi dettagli cambia, dovremmo modificare sia la classe interessata che le classi a essa collegate (ad esempio, Theater).


Questo è un problema legato alla dipendenza tra gli oggetti, e la dipendenza implica un impatto sulle modifiche. Tuttavia, poiché l'obiettivo della progettazione orientata agli oggetti è costruire una comunità di oggetti che collaborano e dipendono l'uno dall'altro, non dobbiamo eliminare a priori le dipendenze, ma dobbiamo mantenere solo le dipendenze minime necessarieed eliminare quelle non necessarie.


Quando la dipendenza tra gli oggetti è eccessiva, si dice che l'accoppiamentoè alto, e maggiore è l'accoppiamento tra due oggetti, maggiore è la probabilità che vengano modificati insieme. Pertanto, l'obiettivo della progettazione è ridurre l'accoppiamento tra gli oggetti per rendere le modifiche più facili.


Migliorare la progettazione

Theater non ha bisogno di sapere se lo spettatore ha una borsa o se il venditore di biglietti vende biglietti alla biglietteria. Theater vuole solo che lo spettatore entri nel teatro. Pertanto, dobbiamo rendere lo spettatore e il venditore di biglietti entità autonome, in modo che gestiscano autonomamente il denaro e l'invito nella borsa e i biglietti e le tariffe di vendita nella biglietteria.


Aumentare l'autonomia

Un oggetto che esegue solo attività strettamente correlate e delega attività non correlate ad altri oggetti si dice che abbia un'elevata coesione. Creare oggetti autonomi che gestiscono i propri dati riduce l'accoppiamento e aumenta la coesione.


Programmazione procedurale e programmazione orientata agli oggetti

  • Procedurale
    • Il metodo enter() di Theater è un processo, mentre Audience, TicketSeller, Bag e TicketOffice sono dati.
    • Il posizionamento di processi e dati in moduli separati è chiamato programmazione procedurale.
    • Ci sono molti codici che violano la nostra intuizione. (ad esempio, lo spettatore gestisce autonomamente denaro e inviti).
    • È difficile limitare l'impatto delle modifiche ai dati.
    • La responsabilità è gestita in modo centralizzato. (Theater gestisce tutto)
  • Orientato agli oggetti
    • Il posizionamento di dati e processi all'interno dello stesso modulo è chiamato programmazione orientata agli oggetti.
    • Possiamo scrivere codice che corrisponde alla nostra intuizione.
    • L'impatto delle modifiche ai dati può essere efficacemente limitato tramite l'incapsulamento.
    • Ogni oggetto è responsabile di se stesso.


Si può migliorare ulteriormente.

  • La classe Bag della classe Audience è ancora un'entità passiva trascinata dalla classe Audience, quindi dobbiamo rendere la classe Bag un'entità autonoma.
  • Anche TicketOffice della classe TicketSeller è gestito a piacimento da TicketSeller. Dobbiamo rendere TicketOffice un'entità autonoma.
    • Tuttavia, dopo la modifica, TicketOffice ha un ulteriore accoppiamento con Audience.
    • Come questo, la progettazione richiede un'attenta valutazione dei compromessi. In questo caso, potremmo concordare di rendere TicketOffice un oggetto relativamente passivo per ridurre l'accoppiamento con Audience.



Sì, è una bugia!

  • Nella realtà, anche se qualcosa è passivo, nel mondo della programmazione orientata agli oggetti, tutto diventa attivo e autonomo.
  • È utile utilizzare la personificazione e pensare agli oggetti passivi come se stessero ridendo, chiacchierando e arrabbiandosi.


Progettazione orientata agli oggetti

Perché è necessaria la progettazione?

  • La progettazione è il posizionamento del codice.
  • Una buona progettazione è quella che soddisfa pienamente le esigenze attuali e allo stesso tempo consente di affrontare i cambiamenti futuri in modo fluido.


Progettazione orientata agli oggetti

  • Il codice modificabile è un codice facile da capire.
  • Il paradigma orientato agli oggetti ci aiuta a scrivere codice nel modo in cui vediamo il mondo.
  • Gli oggetti sono entità autonome che sono responsabili dei propri dati.
  • Una buona progettazione orientata agli oggetti è una progettazione che gestisce correttamente le dipendenze tra gli oggetti che collaborano.


Fonti

  • Oggetti

Commenti0