Sistema di prenotazione film
Esaminare i requisiti
- Si desidera implementare un sistema di prenotazione film online.
- Il film rappresenta le informazioni di base relative al film.
- Come titolo, durata, informazioni sul prezzo, ecc.
- La proiezione rappresenta l'evento in cui il pubblico guarda effettivamente il film.
- Come data di proiezione, ora, numero d'ordine, ecc.
- Le persone prenotano i film, ma in realtà dovrebbero prenotare un determinato proiezionedi un film, per essere precisi.
- Condizioni di sconto
- Disponibilità di sconti sul prezzo
- Condizione d'ordine: utilizzo del numero d'ordine della proiezione per determinare la disponibilità di uno sconto
- Condizione di periodo: utilizzo dell'ora di inizio della proiezione del film per determinare la disponibilità di uno sconto
- Politica di sconto
- Determinare la tariffa scontata
- Politica di sconto in denaro: sconto di un determinato importo dalla tariffa di prenotazione
- Politica di sconto percentuale: sconto di una determinata percentuale sul prezzo intero
- Per ogni film è possibile assegnare una politica di sconto o non assegnarne alcuna, e le condizioni di sconto possono essere combinate con più condizioni di sconto.
- Se una politica di sconto è applicata ma le condizioni di sconto non sono soddisfatte, o se non è applicata alcuna politica di sconto, la tariffa non viene scontata.
Verso la programmazione orientata agli oggetti
Collaborazione, oggetti, classi
- L'orientamento agli oggetti è orientato agli oggetti.
- Non bisogna preoccuparsi di quali attributi e metodi siano necessari per una classe dopo aver deciso la classe.
- È necessario determinare quali oggetti hanno quali stati e comportamenti.
- Gli oggetti devono essere visti non come entità indipendenti, ma come membri di una comunità collaborativa.
Struttura del programma che segue la struttura del dominio
- Il dominio si riferisce all'area in cui l'utente utilizza il programma per risolvere un problema.
<span class="image-inline ck-widget" contenteditable="false"><img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fe7d22a03-4a24-40e9-8068-bd03b9fd816b%2FUntitled.png?table=block&id=3f1931fc-8ef9-470a-8189-3727146638f6&spaceId=b453bd85-cb15-44b5-bf2e-580aeda8074e&width=2000&userId=80352c12-65a4-4562-9a36-2179ed0dfffb&cache=v2" alt="Untitled" style="aspect-ratio:2000/438;" width="2000" height="438"></span>
- In generale, il nome di una classe deve essere lo stesso o almeno simile al nome del concetto di dominio corrispondente.
- Anche la relazione tra le classi deve essere il più possibile simile alla relazione tra i concetti di dominio, in modo che la struttura del programma sia facile da capire e prevedere.
Implementazione della classe
- La classe è divisa in interno ed esterno, e per progettare una buona classe, è necessario decidere quali parti rendere pubbliche e quali nascondere.
- Gli attributi dell'oggetto sono bloccati come privati e i metodi necessari per modificare lo stato interno sono aperti come pubblici.
- La separazione tra interno ed esterno della classe fornisce agli sviluppatori la libertà di implementazione garantendo l'autonomia dell'oggetto.
Oggetto autonomo
- L'oggetto deve essere un'entità autonoma con stato e comportamento.
- Il raggruppamento di dati e funzioni all'interno dell'oggetto è chiamato incapsulamento.
- Il controllo di accesso riduce le interferenze esterne, consentendo all'oggetto di decidere autonomamente il proprio comportamento.
- Il principio di separazione tra interfaccia e implementazione è un principio chiave che deve essere seguito nella programmazione orientata agli oggetti.
- Interfaccia pubblica: parte accessibile dall'esterno
- Implementazione: parte accessibile solo dall'interno
Libertà dello sviluppatore
- Il ruolo dello sviluppatore è diviso in sviluppatore di classi e sviluppatore client.
- Lo sviluppatore di classi aggiunge un nuovo tipo di dati
- Lo sviluppatore client utilizza il tipo di dati aggiunto dallo sviluppatore di classi
- Occultamento dell'implementazione
- Lo sviluppatore di classi può nascondere l'implementazione interna fornendo solo le parti necessarie allo sviluppatore client.
- Lo sviluppatore client deve conoscere solo l'interfaccia, quindi può ridurre la quantità di informazioni da gestire.
Comunità di oggetti collaborativi
- Quando si rappresenta il denaro, è meglio impacchettarlo come un oggetto, come Money, invece di dichiarare semplicemente una variabile di tipo Long. Utilizzando oggetti, il significato viene trasmesso meglio e le elaborazioni ridondanti possono essere eseguite in un unico punto.
- L'interazione tra gli oggetti per implementare una funzione del sistema è chiamata collaborazione.
Una breve storia sulla collaborazione
- L'unico modo in cui un oggetto può interagire con un altro oggetto è inviare o ricevere messaggi.
- Il proprio metodo per elaborare i messaggi ricevuti è chiamato metodo.
- È importante distinguere tra messaggi e metodi, e questo è il punto di partenza del concetto di polimorfismo.
Calcolo della tariffa scontata
Iniziare la collaborazione per il calcolo della tariffa scontata
- La classe Movie non contiene la logica dettagliata relativa alla politica di sconto e la delega all'interfaccia DiscountPolicy. È davvero importante utilizzare ereditarietà, polimorfismo e astrazione.
Politica di sconto e condizioni di sconto
<span class="image-inline ck-widget" contenteditable="false"><img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F7b9b27a5-0dac-4ba7-9552-05b7f8fbdecd%2FUntitled.png?table=block&id=3264f189-6e12-4a55-94d2-75b851320c7a&spaceId=b453bd85-cb15-44b5-bf2e-580aeda8074e&width=2000&userId=80352c12-65a4-4562-9a36-2179ed0dfffb&cache=v2" alt="Untitled" style="aspect-ratio:2000/535;" width="2000" height="535"></span>
Ereditarietà e polimorfismo
Dipendenza in fase di compilazione e dipendenza in fase di esecuzione
- La dipendenza del codice e la dipendenza al momento dell'esecuzione possono essere diverse.
- Più le dipendenze sono diverse, più il codice è difficile da capire, ma più il codice è flessibile ed estensibile.
Programmazione basata sulla differenza
- L'ereditarietà consente di aggiungere facilmente e rapidamente nuove classi in base alle classi esistenti e di riutilizzare l'implementazione della classe padre.
- Il metodo per creare una nuova classe aggiungendo solo le parti diverse dalla classe padre è chiamato programmazione basata sulla differenza.
Ereditarietà e interfaccia
- L'ereditarietà fa sì che la classe figlia erediti tutte le interfacce fornite dalla classe padre.
- L'interfaccia definisce un elenco di messaggi che un oggetto può comprendere.
- Movie invia il messaggio calculateDiscountAmount a DiscountPolicy. Per Movie, non importa quale istanza di classe risponda, basta che risponda correttamente.
- Pertanto, sia AmountDiscountPolicy che PercentDiscountPolicy possono collaborare con Movie al posto di DiscountPolicy.
- Questo tipo di sostituzione di una classe figlia con una classe padre è chiamato upcasting. Questo perché sembra che la classe figlia venga automaticamente convertita nel tipo della classe padre.
Polimorfismo
- Il polimorfismo è la capacità di rispondere in modo diverso a seconda del tipo di oggetto quando si riceve lo stesso messaggio.
- Movie invia lo stesso messaggio, ma il metodo effettivamente eseguito dipende dalla classe dell'oggetto che riceve il messaggio.
- Il polimorfismo si basa sul fatto che la dipendenza in fase di compilazione e la dipendenza in fase di esecuzione del programma possono essere diverse.
- Poiché il polimorfismo determina il metodo da eseguire al momento dell'esecuzione, è chiamato binding ritardato o binding dinamico.
Interfaccia e polimorfismo
- Se si desidera condividere solo l'interfaccia e non è necessario condividere l'implementazione, è possibile utilizzare un'interfaccia invece di una classe astratta.
Astrazione e flessibilità
Il potere dell'astrazione
- Vantaggi dell'astrazione
- Esaminando solo il livello di astrazione, è possibile descrivere la politica dei requisiti a un livello elevato.
- Il design diventa più flessibile.
Design flessibile
- L'astrazione impedisce che il design sia legato a situazioni specifiche, consentendo di creare un design flessibile.
Compromesso tra classe astratta e interfaccia
- Attualmente, NoneDiscountPolicy non è in realtà necessario perché, nel metodo calculateDiscountAmount() di DiscountPolicy, se non ci sono condizioni di sconto, viene restituito 0, quindi non ci sono problemi. Tuttavia, è stato aggiunto perché l'utente deve fornire una politica Nessuno come argomento di Movie.
- Pertanto, la classe NoneDiscountPolicy è confusa e, modificandola come mostrato di seguito, è più facile da capire.
- Come mostrato sopra, DiscountPolicy viene astratto come un'interfaccia e viene diviso in NoneDiscountPolicy, che è la sua implementazione, e DefaultDiscountPolicy, che rappresenta una politica di sconto generale.
<span class="image-inline ck-widget" contenteditable="false"><img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F712983a9-3937-4265-82fe-66a144c44a0f%2FUntitled.png?table=block&id=f5ca651c-d03c-4a6c-97e9-7443ee5649a0&spaceId=b453bd85-cb15-44b5-bf2e-580aeda8074e&width=2000&userId=80352c12-65a4-4562-9a36-2179ed0dfffb&cache=v2" alt="Untitled" style="aspect-ratio:2000/886;" width="2000" height="886"></span>
- Si potrebbe pensare che aggiungere un'interfaccia solo per NoneDiscountPolicy comporti una complessità eccessiva rispetto al guadagno di efficienza.
- È necessario essere consapevoli del fatto che tutto ciò che riguarda l'implementazione può essere oggetto di un compromesso e progettare di conseguenza. In altre parole, ogni riga di codice deve avere una ragione valida.
Riutilizzo del codice
- L'ereditarietà può essere utilizzata per riutilizzare il codice.
- Tuttavia, per il riutilizzo del codice, è preferibile utilizzare la composizione rispetto all'ereditarietà.
- Nel codice corrente, il modo in cui Movie riutilizza il codice di DiscountPolicy è proprio la composizione.
- Se Movie fosse la classe padre e fosse suddivisa in AmountDiscountMovie e PercentDiscountMovie, si potrebbe dire che viene utilizzata l'ereditarietà.
Ereditarietà
- Svantaggi dell'ereditarietà
- Viola l'incapsulamento.
- È necessario conoscere la struttura interna della classe padre.
- È più probabile che la classe figlia debba essere modificata quando la classe padre viene modificata.
- Rende il design meno flessibile.
- La relazione tra la classe padre e la classe figlia viene decisa in fase di compilazione.
- Non è possibile modificare il tipo di oggetto in fase di esecuzione.
- Tuttavia, la composizione consente di sostituire le istanze in fase di esecuzione tramite un metodo come changeDiscountPolicy() lato oggetto che utilizza l'oggetto.
- Viola l'incapsulamento.
Composizione
- Il metodo per riutilizzare il codice solo tramite messaggi definiti nell'interfaccia è chiamato composizione.
- Consente di implementare l'incapsulamento e di mantenere un accoppiamento lasco.
- Quando si riutilizza un'interfaccia per il polimorfismo, è necessario utilizzare una combinazione di ereditarietà e composizione.
- Ad esempio, l'interfaccia DiscountPolicy deve utilizzare l'ereditarietà per implementare le sue sottoclassi.
Fonti
- Oggetto
Commenti0