Video: Building Dynamic Web Apps with Laravel by Eric Ouyang 2024
Il concetto di ereditarietà, e quindi il factoring, in C ++ consente a una classe di ereditare le proprietà di una classe base. L'ereditarietà ha un numero di scopi; il principale vantaggio dell'ereditarietà è la capacità di evidenziare la relazione tra le classi. Questa è la cosiddetta relazione IS_A - un Forno a Microonde IS_A e cose del genere.
Il factoring è ottimo se si effettuano le correlazioni corrette. Ad esempio, il rapporto tra forno a microonde e forno convenzionale sembra naturale. Affermare che il forno a microonde è un tipo speciale di tostapane, e tu sei diretto verso guai. È vero, entrambi rendono le cose calde, entrambi usano l'elettricità, e sono entrambi trovati in cucina, ma la somiglianza finisce lì - un forno a microonde non può fare il pane tostato e un tostapane non può fare i nachos.
Identificare le classi inerenti a un problema e disegnare le relazioni corrette tra queste classi è un processo noto come factoring . (La parola è legata all'aritmetica che sei stato costretto a fare nella scuola elementare: calcolando i meno comuni denominatori, ad esempio, 12 è uguale a 2 volte 2 volte 3.)
Ecco come puoi usare ereditarietà per semplificare i tuoi programmi usando un esempio di conto bancario. Supponiamo che ti sia stato chiesto di scrivere un semplice programma bancario che implementasse il concetto di un conto di risparmio e un conto corrente.
I programmatori orientati agli oggetti hanno trovato un modo conciso per descrivere i punti salienti di una classe in un disegno. I controllo delle classi e risparmio sono mostrati in questa figura. (Questo è solo uno dei tanti modi per esprimere graficamente la stessa cosa.)
Verifica e Risparmio. "> Classi indipendenti Verifica e Risparmi.Per leggere questa figura e le altre figure, ricordare quanto segue:
-
La casella grande è la classe, con il nome della classe in alto.
-
I nomi nelle caselle sono funzioni membro.
-
I nomi non nelle caselle sono membri dei dati.
-
I nomi che si estendono in parte fuori dalle scatole sono membri accessibili pubblicamente; cioè, a questi membri è possibile accedere da funzioni che non fanno parte della classe o dei suoi discendenti. I membri che sono completamente dentro la scatola non sono accessibili dall'esterno della classe.
-
Una freccia spessa rappresenta la relazione IS_A.
-
Una freccia sottile rappresenta la relazione HAS_A.
Una vettura IS_A Veicolo , ma una vettura HAS_A Motore .
Puoi vedere nella prima figura che le Verifica delle classi e Risparmio hanno molto in comune. Ad esempio, entrambe le classi hanno una funzione membro di prelievo () e deposito ().Poiché le due classi non sono identiche, tuttavia, devono rimanere come classi separate. (In un'applicazione bancaria reale, le due classi sarebbero molto più diverse rispetto a questo esempio.) Tuttavia, ci dovrebbe essere un modo per evitare questa ripetizione.
Si potrebbe avere una di queste classi ereditate dall'altra. Il risparmio ha più membri di Controllo, in modo da consentire a Risparmi di ereditare da Verifica. Questa disposizione è mostrata in questa prossima figura.
La classe Risparmio eredita tutti i membri. La classe viene completata con l'aggiunta del membro dati noWithdrawals e sovrascrivendo la funzione withdraw () . Devi annullare il prelievo () perché le regole per prelevare denaro da un conto di risparmio sono diverse da quelle per prelevare denaro da un conto corrente.
Risparmio implementato come sottoclasse di Verifica. "> Risparmio implementato come sottoclasse di Verifica.Sebbene lasciare che Risparmio erediti da Controllare è laborioso, non è completamente soddisfacente. Il problema principale è che, come il peso elencato sulla mia patente di guida, travisa la verità. Questa relazione di ereditarietà implica che un conto di risparmio è un tipo speciale di conto corrente, che non è.
Tali travisamenti confondono il programmatore, sia di oggi che di domani. Un giorno, un programmatore che non conosce i nostri trucchi di programmazione dovrà leggere e capire cosa fa il nostro codice. Le rappresentazioni fuorvianti sono difficili da conciliare e comprendere.
Inoltre, tali travisamenti possono portare a problemi lungo la strada. Supponiamo, ad esempio, che la banca cambi le sue politiche rispetto ai conti correnti. Supponiamo che decida di addebitare un costo di servizio sui conti correnti solo se il saldo minimo scende al di sotto di un determinato valore durante il mese.
Una modifica come questa può essere facilmente gestita con modifiche minime alla classe Verifica. Dovrai aggiungere un nuovo membro dati alla classe Controllando per tenere traccia del saldo minimo durante il mese. Usciamo su un arto e chiamiamolo minimumBalance.
Ma ora hai un problema. Poiché Risparmio eredita da Controllo, Risparmio ottiene anche questo nuovo membro dati. Non ha alcuna utilità per questo membro perché il saldo minimo non influisce sui conti di risparmio, quindi si limita a stare lì. Ricorda che ogni oggetto account di controllo ha questo extra minimumBalance membro. Un membro dati aggiuntivo potrebbe non essere un grosso problema, ma aggiunge ulteriore confusione.
Cambiamenti come questo si accumulano. Oggi è un membro dati extra - domani è una funzione membro modificata. Alla fine, la classe del conto di risparmio sta portando un sacco di bagaglio extra che è applicabile solo ai conti correnti.
Ora la banca ritorna e decide di cambiare la politica del conto di risparmio. Ciò richiede di modificare alcune funzioni in Verifica. Cambiamenti come questo nella classe base si propagano automaticamente nella sottoclasse a meno che la funzione non sia già stata sostituita nella sottoclasse Risparmi.
Ad esempio, supponiamo che la banca decida di distribuire i tostapane per ogni deposito nel conto corrente. Senza la banca (oi suoi programmatori) che lo conoscono, i depositi sui conti correnti risulterebbero automaticamente nelle donazioni di tostapane. A meno che tu non stia molto attento, le modifiche a Controllo potrebbero apparire inaspettatamente in Risparmi.
Come puoi evitare questi problemi? Affermare che Controllare è un caso speciale di Risparmio cambia ma non risolve il nostro problema. Quello di cui hai bisogno è una terza classe (chiamala Account, solo per i sorrisi) che racchiude le cose che sono comuni tra Verifica e Risparmio, come mostrato qui.
Verifica e Risparmio su un comune Account classe. "> Basamento Verifica e Risparmio su un comune Account classe.In che modo la creazione di un nuovo account risolve i problemi? Innanzitutto, creare una nuova classe Account è una descrizione più accurata del mondo reale (qualunque cosa sia). Certo, c'è davvero qualcosa di conosciuto come account. Conti di risparmio e conti correnti sono casi speciali di questo concetto più fondamentale.
Inoltre, la classe Risparmio è isolata dalle modifiche alla classe Verifica (e viceversa). Se la banca istituisce una modifica fondamentale a tutti gli account, è possibile modificare Account, e tutte le sottoclassi erediteranno automaticamente la modifica. Ma se la banca cambia politica solo per il controllo degli account, è possibile modificare solo la classe di conto Verifica senza influire su Risparmi.
Questo processo di eliminazione delle proprietà comuni da classi simili è l'essenza del factoring di classe .
Il factoring è legittimo solo se la relazione di ereditarietà corrisponde alla realtà. Factoring insieme una classe Mouse e Joystick perché sono entrambi dispositivi di puntamento hardware è legittimo. Factoring insieme una classe Mouse e Visualizza perché entrambi fanno chiamate di sistema operativo di basso livello non lo è.