Poiché le applicazioni PHP diventano sempre più complesse, può essere facile finire con un pasticcio di codice che rende quasi impossibile la manutenzione. L'applicazione del concetto di applicazioni a livelli può aiutare ad alleviare alcune delle difficoltà nel mantenere applicazioni complesse.
La programmazione a livelli è la pratica di tenere diversi componenti, idee o lingue separate l'una dall'altra.
Nello sviluppo front-end, il markup a livelli utilizzava fogli di stile esterni e JavaScript.
Collegando a un file CSS invece di incorporare gli stili nel markup HTML, diventa più facile cambiare il file
formattazione dei tuoi siti Web perché ora tutte le informazioni sullo stile vengono memorizzate in un unico posto, separate
dal markup del documento. E più pagine HTML possono inserire lo stesso file CSS, l'intero sito
può essere aggiornato in base allo stile semplicemente cambiando una riga di CSS.
Nello sviluppo back-end si applicano le stesse regole, ma abbiamo a che fare con componenti diversi. In termini generali, lo siamo
guardando tre livelli: il Banca dati (memorizzazione e recupero dei dati), Attività commerciale
(elaborazione e gestione dei dati), e Presentazione (come vengono visualizzati i dati) livelli.
Potrebbe non essere immediatamente ovvio, ma separare le tue applicazioni in una struttura a più livelli sarà enorme
impatto sulla capacità del tuo codice di cambiare in futuro. Ad esempio, se hai un sistema di blogging impostato, e
diventa necessario creare un feed RSS per il blog, un'applicazione con livelli adeguati ti permetterebbe semplicemente
configurare un modello RSS, quindi chiamare il database e le funzioni aziendali che hai già scritto.
Al contrario, se il tuo cliente improvvisamente ha deciso che PostgreSQL era una scelta migliore per la loro organizzazione
di MySQL, dovresti solo riscrivere le funzioni del tuo database, tutto senza toccare il business o
logica di presentazione dell'applicazione.
In termini di riusabilità, è possibile avere più funzionalità di database (supportando MySQL, PostgreSQL e
Oracle, ad esempio), che potrebbe essere facilmente inserito in nuovi rilasci dell'applicazione utilizzando solo alcuni
linee di codice in un posto, piuttosto che modificare diverse righe del codice su più funzioni.
Per iniziare, prendiamo un compito abbastanza semplice, estraendo il titolo e il testo del corpo di una voce da un database,
creando una versione abbreviata della voce e inserendo i dati nel markup HTML e attivandoli
completamente nel modo sbagliato. Nel seguente codice, scriveremo una funzione per eseguire tutti i nostri
compiti:
function displayEntry () $ entryDisp = NULL; // Ottieni le informazioni dal database $ sql = "SELECT title, entry FROM entries WHERE page =" blog ""; $ r = mysql_query ($ sql) o die (mysql_error ()); while ($ entry = mysql_fetch_assoc ($ r)) $ title = $ entry ['title']; $ text = $ entry ['entry']; // Crea l'anteprima del testo $ textArray = esplode (", $ text); $ preview = NULL; for ($ i = 0; $ i<24; $i++) $preview .= $textArray[$i] ."; $preview .= $textArray[24] . '… '; // Format the entries $entryDisp .= <<$ titolo $ anteprima
ENTRY_DISPLAY; return $ entryDisp;
Questo codice emette un markup HTML lungo queste linee:
Entry One
Questa è la descrizione abbreviata della voce numero uno. Visualizza le prime 25 parole della voce e poi si stacca con un'ellissi ...
Entrata due
Questa è la descrizione abbreviata della voce numero due. Visualizza le prime 25 parole della voce e poi si stacca con un'ellissi ...
Anche se questo potrebbe sembrare logico, in realtà è davvero indesiderabile. Andiamo su ciò che rende questo
codificare un approccio non ottimale.
Scarsa leggibilità-Questo codice è diluito. Il suo scopo, benché documentato nei commenti
(sorta di), è difficile da discernere. Se hai scritto questo, poi sei tornato dopo sei mesi, non sarebbe stato istantaneo
chiaro cosa stava succedendo, il che significa che alcuni secondi / minuti sprecati cercando di interpretare il tuo codice.
Troppo stretto a fuoco-Questa funzione è paralizzata dalla sua specificità: la query del database funziona solo per un tipo di voce;
la creazione dell'anteprima del testo è hard-coded nella funzione; la formattazione è specifica per il tipo di voce
essere visualizzato. Per creare un'implementazione leggermente diversa di questa funzionalità, saremmo obbligati a farlo
creare una seconda funzione che sembrava quasi esattamente la stessa, anche se tutto ciò di cui avevamo bisogno di cambiare era il numero di
parole nell'anteprima del testo.
Mancanza di scalabilità-Questo è strettamente correlato all'idea di essere troppo ristretto; se vogliamo aggiungere più funzionalità (come
come collegamento o immagine), la nostra funzione diventerà più grande e più difficile da gestire. E se vogliamo aggiungere
condizioni che influenzano il modo in cui viene visualizzata una voce? È facile vedere come la programmazione come questa consente al codice di
diventa rapidamente esteso e ingestibile.
Questo è il problema radicale che sta causando tutti i problemi di cui sopra.
Combinando tutte e tre le nostre logiche
tipi, finiamo con un groviglio di codice stretto, disordinato, difficile da gestire, quasi impossibile da riutilizzare.
Immagina un'applicazione in cui sia stato creato ogni tipo di display (feed RSS, anteprima di voci, visualizzazione di voci complete, ecc.)
una funzione come quella sopra, con l'accesso al database, la logica aziendale e la logica di presentazione tutti scritti insieme.
Ora immagina che ci siano nove pagine sul sito, ognuna delle quali ha le proprie funzioni di visualizzazione e anteprima.
Anche supponendo che l'applicazione sia veramente semplice e che ci siano solo due funzioni per pagina del sito, siamo fermi
guardando quasi venti funzioni che dovranno essere aggiornate se le modifiche diventano necessarie.
Per migliorare il codice sopra, diffonderemo i nostri diversi tipi di logica attraverso diverse funzioni. Se fatto correttamente, noi
dovrebbe finire con un insieme di funzioni altamente riutilizzabili e facilmente comprensibili che si sommano per eseguire una varietà di compiti.
Per iniziare, pianificheremo le funzionalità necessarie per avere un'idea migliore
come dovrebbe essere costruito:
Come potete vedere, il nostro piano identifica chiaramente un database, un business e un livello presentazionale. Possiamo ora
scrivere funzioni per soddisfare ognuno di questi passaggi con relativa facilità.
Per ottenere informazioni dal database, scriveremo una funzione molto semplice. Incoraggiare una buona codifica
pratica, ho intenzione di usare l'estensione mysqli, ma
Non mi concentrerò su come funziona. Se non lo stai già utilizzando, ti incoraggio ad esplorare mysqli o a
estensione simile (ad esempio PDO) per proteggere le tue query MySQL contro
attacchi di iniezione.
Quindi passiamo direttamente al codice:
function getDataFromDB ($ page) / * * Connessione a un server MySQL * / $ mysqli = new mysqli ('localhost', 'user', 'password', 'world'); if (mysqli_connect_errno ()) printf ("Connessione fallita:% s \ n", mysqli_connect_error ()); Uscita; / * * Creare un'istruzione preparata per richiamare tutte le voci da una pagina * / if ($ stmt = $ mysqli-> prepare ('SELECT title, entry FROM entries WHERE page =?')) / * * Creare un multi- array dimensionale per memorizzare * le informazioni da ciascuna voce * / $ entries = array (); / * * Collega il parametro passato alla query, recupera i dati e posizionalo * nell'array $ voci per un utilizzo successivo * / $ stmt-> bind_param ("s", $ page); $ Stmt-> execute (); $ stmt-> bind_result ($ title, $ entry); while ($ stmt-> fetch ()) $ entries [] = array ('title' => $ title, 'entry' => $ entry); / * * Distruggi il set di risultati e libera la memoria utilizzata per esso * / $ stmt-> close (); / * * Chiudi la connessione * / $ mysqli-> close (); / * * Restituisce l'array * / return $ entries;
Se si analizza ciò che questa funzione sta facendo, stiamo letteralmente solo richiedendo
due colonne (titolo e voce) dalla nostra tabella (voci), quindi memorizzando ciascuna voce
in un array associativo multidimensionale, che è il valore di ritorno del
funzione. Passiamo un parametro, $ page, in modo che possiamo determinare quale pagina siamo
afferrando informazioni per. In tal modo, abbiamo ora creato una funzione che funzionerà
per ogni pagina del nostro sito (a condizione che abbiano tutti un campo 'titolo' e 'voce').
Si noti che la nostra funzione non fa nulla maniglia i dati; semplicemente agisce
come corriere, afferrando le informazioni che chiediamo e trasmettendole a qualunque cosa
viene dopo. Questo è importante, perché se facesse qualcosa di più, saremmo nel
regno della logica aziendale.
La risposta breve è che consente il database
astrazione, che significa essenzialmente che i dati potrebbero essere migrati da MySQL
in un altro formato di database, come PostgreSQL o Oracle, tutto senza
cambiando le funzioni di gestione dei dati (livello aziendale), poiché l'output sarebbe
ancora semplicemente essere un array associativo multidimensionale contenente voci con a
titolo e colonna di iscrizione, indipendentemente dal tipo di database che stiamo utilizzando.
Con i dati caricati nel nostro array, possiamo iniziare a elaborare le informazioni
soddisfare i nostri scopi. In questo esempio, stiamo cercando di creare un'anteprima della voce. Nel
Nel primo esempio, la lunghezza dell'anteprima era codificata nella funzione,
che abbiamo deciso è una cattiva pratica. In questa funzione, passeremo due parametri
al nostro codice: il testo da elaborare e il numero di parole che vogliamo mostrare come
la nostra anteprima.
Iniziamo guardando la funzione:
function createTextPreview ($ text, $ length = 25) / * * Spezza il testo negli spazi e crea la variabile di anteprima * / $ words = explode (", $ text); $ preview = NULL; / * * Esegui a loop per aggiungere parole alla variabile di anteprima * / if ($ length < count($words)) for($i=0; $i<$length; $i++) $preview .= $words[$i] ."; // Add the space back in between words $preview .= $words[$length] . '… '; // Ellipsis to indicate preview else /* * If the entry isn't as long as the specified preview length, simply * return the whole entry. */ $preview = $text; /* * Return the preview */ return $preview;
Nella funzione sopra, verifichiamo semplicemente che il numero di parole nel fornito
la voce è maggiore del numero di parole che vogliamo mostrare nella nostra anteprima, quindi
aggiungi parole alla variabile di anteprima $ appena creata una alla volta fino a quando non colpiamo la nostra
lunghezza del target, a quel punto aggiungiamo un'ellissi e restituiamo $ preview.
Proprio come nel nostro livello di database, stiamo mantenendo il codice entro i limiti del
livello aziendale. Tutto ciò che stiamo facendo è creare un'anteprima di testo; Non c'è
interazione con il database e nessun elemento di presentazione come HTML
markup.
Infine, dobbiamo visualizzare i dati che abbiamo recuperato ed elaborato. Per noi
scopi, lo mostreremo con un markup HTML estremamente semplice:
L'idea alla base di questo codice è semplice: in primo luogo, caricare le voci utilizzando il nostro
funzione di database, quindi scorrere le voci, accorciando il testo della voce
usando la nostra funzione di anteprima e quindi inserendo il titolo e l'anteprima della voce
markup di presentazione.
Ora, per cambiare il layout delle anteprime delle voci, solo due righe di
HTML deve essere regolato. Questo è molto diverso da quello dell'originale
funzione che gestiva tutti e tre i livelli.
Vorrei sottolineare che l'esempio sopra riportato è molto semplice, e si intende solo per
dimostrare il concetto di programmazione a più livelli. L'idea è che mantenendo il
diversi tipi di logica di programmazione separati, è possibile aumentare notevolmente il
leggibilità e manutenibilità del tuo codice.
NOTA: c'è un grande articolo
su TheDailyWTF.com discutendo l'uso e l'uso improprio della progettazione di software multilivello, e
commento meraviglioso sul
articolo che presenta opinioni divergenti. Le applicazioni multilivello sono estremamente utili, ma anche facili da usare
fraintendere e complicare eccessivamente, quindi ricordarsi di pianificare accuratamente il software prima di costruire per evitare di causare
più problemi di quelli che stai risolvendo.
Hai qualche idea sulle applicazioni a più livelli? Che passi stai facendo?
massimizzare la facilità di manutenzione e le modifiche future nel codice che scrivi? Lasciateci
sapere nei commenti!