Naarmate PHP-applicaties steeds complexer worden, kan het gemakkelijk zijn om een hele warboel van code te krijgen die onderhoud bijna onmogelijk maakt. Toepassing van het concept van gelaagde applicaties kan een deel van de moeilijkheid bij het onderhouden van complexe applicaties helpen verlichten.
'Tiered programming' is de praktijk om verschillende componenten, ideeën of talen gescheiden van elkaar te houden.
In de front-end ontwikkeling zou gelaagde markup gebruikmaken van externe stylesheets en JavaScript.
Door een koppeling te maken naar een CSS-bestand in plaats van stijlen in te bedden in uw HTML-markup, wordt het eenvoudiger om de te wijzigen
formattering van uw websites omdat nu alle stylinginformatie handig op één plek wordt opgeslagen, gescheiden
van de opmaak van het document. En meerdere HTML-pagina's kunnen precies hetzelfde CSS-bestand, uw hele site, binnenhalen
kan op stijl worden bijgewerkt door eenvoudigweg één regel CSS te wijzigen.
In de back-end ontwikkeling zijn dezelfde regels van toepassing, maar we hebben te maken met verschillende componenten. In algemene termen, we zijn
kijkend naar drie niveaus: de Database (opslaan en ophalen van gegevens), Bedrijf
(verwerking en verwerking van gegevens), en Presentatie (hoe gegevens worden weergegeven) niveaus.
Het is misschien niet meteen duidelijk, maar het scheiden van uw applicaties in een gelaagde structuur zal enorm zijn
invloed hebben op het vermogen van uw code om in de toekomst te veranderen. Als u bijvoorbeeld een blogsysteem hebt ingesteld, en
het wordt noodzakelijk om een RSS-feed voor de blog te maken, een correct gelaagde toepassing zou u eenvoudig toestaan
stel een RSS-sjabloon op en bel vervolgens de database en zakelijke functies die u al hebt geschreven.
Aan de andere kant, als uw klant ineens zou besluiten dat PostgreSQL een betere keuze was voor hun organisatie
dan MySQL, zou je alleen je databasefuncties moeten herschrijven, allemaal zonder het bedrijf of
presentatielogica van de applicatie.
In termen van herbruikbaarheid zou je meerdere databasefunctionaliteiten kunnen hebben (ondersteuning voor MySQL, PostgreSQL, en
Oracle, bijvoorbeeld), die met een paar licenties gemakkelijk in nieuwe implementaties van uw toepassing kunnen worden geplaatst
coderegels op één plaats, in plaats van meerdere regels van uw code over meerdere functies te bewerken.
Laten we om te beginnen een vrij eenvoudige taak nemen: de titel en hoofdtekst van een item uit een database halen,
een verkorte versie van het item maken en de gegevens in HTML-markeringen plaatsen - en er verder over gaan
helemaal op de verkeerde manier. In de volgende code zullen we één functie schrijven om al onze taken uit te voeren
taken:
function displayEntry () $ entryDisp = NULL; // Haal de informatie uit de database op $ sql = "SELECT title, entry FROM entries WHERE page =" blog ""; $ r = mysql_query ($ sql) of sterf (mysql_error ()); while ($ entry = mysql_fetch_assoc ($ r)) $ title = $ entry ['title']; $ text = $ entry ['entry']; // Maak het tekstvoorbeeld $ textArray = ontploffen (", $ tekst); $ preview = NULL; for ($ i = 0; $ i<24; $i++) $preview .= $textArray[$i] ."; $preview .= $textArray[24] . '… '; // Format the entries $entryDisp .= <<$ title $ voorvertoning
ENTRY_DISPLAY; return $ entryDisp;
Deze code voert HTML-markup uit volgens deze regels:
Invoer één
Dit is de verkorte beschrijving van nummer één. Het geeft de eerste 25 woorden van de invoer weer en verdwijnt vervolgens met een ellips ...
Invoer twee
Dit is de verkorte beschrijving van nummer twee. Het geeft de eerste 25 woorden van de invoer weer en verdwijnt vervolgens met een ellips ...
Hoewel dit misschien logisch lijkt, is het eigenlijk echt onwenselijk. Laten we gaan kijken naar wat dit maakt
codeer een minder dan optimale benadering.
Slechte leesbaarheid-Deze code is verdund. Het doel ervan, hoewel gedocumenteerd in de opmerkingen
(soort van), is moeilijk te onderscheiden. Als je dit had geschreven, kwam je er binnen zes maanden weer op terug, het zou niet meteen zijn
duidelijk wat er aan de hand was, wat betekent dat een paar seconden / minuten verspild proberen om je eigen code te interpreteren.
Te smal in focus-Deze functie is verlamd door zijn specificiteit: de databasequery werkt slechts voor één type item;
het maken van de tekstvoorvertoning is hard gecodeerd in de functie; de opmaak is specifiek voor het type invoer
wordt weergegeven. Om een iets andere implementatie van deze functionaliteit te creëren, zouden we gedwongen worden
creëer een tweede functie die er bijna hetzelfde uitziet, zelfs als alles wat we nodig hadden om te veranderen het aantal was
woorden in het tekstvoorbeeld.
Gebrek aan schaalbaarheid-Dit is vrij nauw verbonden met het idee om te nauw in focus te zijn; als we meer functionaliteit willen toevoegen (zoals
als een link of afbeelding), wordt onze functie groter en moeilijker te beheren. En wat als we willen toevoegen
voorwaarden die van invloed zijn op hoe een item wordt weergegeven? Het is gemakkelijk om te zien hoe programmeren als dit code mogelijk maakt
snel uitgestrekte en onhandelbaar worden.
Dit is het ingrijpende probleem dat alle bovengenoemde problemen veroorzaakt.
Door alle drie onze logica te combineren
types, we eindigen met een smal, rommelig, moeilijk te beheren, bijna onmogelijk om opnieuw te gebruiken kluwen van code.
Stelt u zich een toepassing voor waarin elk type display (RSS-feed, invoervoorbeeld, volledige invoerweergave, enz.) Werd gebouwd
een functie zoals hierboven, waarbij de databasetoegang, bedrijfslogica en presentatielogica allemaal samen zijn geschreven.
Stel je nu voor dat er negen pagina's op de site zijn, die allemaal hun eigen scherm voor het invoeren en bekijken van voorbeelden hebben.
Zelfs als we aannemen dat de toepassing heel eenvoudig is en dat er slechts twee functies per pagina op de site zijn, zijn we nog steeds
bijna kijken twintig functies die moeten worden bijgewerkt als veranderingen noodzakelijk worden.
Om de bovenstaande code te verbeteren, zullen we onze verschillende soorten logica over verschillende functies verspreiden. Als dat goed gebeurt, wij
moet eindigen met een set van zeer herbruikbare, gemakkelijk te begrijpen functies die een stapel taken uitvoeren om verschillende taken uit te voeren.
Om te beginnen, plannen we de benodigde functionaliteit uit om een beter beeld te krijgen
hoe het moet worden opgebouwd:
Zoals je kunt zien, ons plan identificeert duidelijk een database, bedrijfs- en presentatielaag. We kunnen het nu
schrijf functies om elk van deze stappen met relatief gemak uit te voeren.
Om informatie uit de database te halen, gaan we een heel eenvoudige functie schrijven. Om goede codering aan te moedigen
oefen, ik ga de mysqli-extensie gebruiken, maar
Ik ga me niet concentreren op hoe het werkt. Als je het niet al gebruikt, raad ik je aan om mysqli of een te verkennen
soortgelijke extensie (dat wil zeggen PDO) om uw MySQL-query's te beveiligen tegen
injectie aanvallen.
Laten we dus meteen naar de code springen:
functie getDataFromDB ($ page) / * * Maak verbinding met een MySQL-server * / $ mysqli = new mysqli ('localhost', 'user', 'password', 'world'); if (mysqli_connect_errno ()) printf ("Connect failed:% s \ n", mysqli_connect_error ()); Uitgang; / * * Maak een voorbereide instructie om alle items van een pagina te trekken * / if ($ stmt = $ mysqli-> prepare ('SELECT-titel, item FROM ingangen WHERE-pagina =?')) / * * Maak een multi- dimensionale array om * de informatie van elke entry op te slaan * / $ entries = array (); / * * Bind de doorgegeven parameter aan de query, haal de gegevens op en plaats * deze in de array $ entries voor later gebruik * / $ stmt-> bind_param ("s", $ page); $ Stmt-> execute (); $ stmt-> bind_result ($ title, $ entry); while ($ stmt-> fetch ()) $ entries [] = array ('title' => $ title, 'entry' => $ entry); / * * Vernietig de resultatenset en maak het gebruikte geheugen vrij * / $ stmt-> close (); / * * Sluit de verbinding * / $ mysqli-> close (); / * * Retourneer de array * / return $ entries;
Als je opsplitst wat deze functie doet, vragen we dat letterlijk
twee kolommen (titel en invoer) uit onze tabel (vermeldingen) en vervolgens elk item op te slaan
in een multidimensionale associatieve array, de retourwaarde van de
functie. We geven een parameter door, $ pagina, zodat we kunnen bepalen welke pagina we zijn
informatie verzamelen voor. We hebben nu een functie gemaakt die werkt
voor elke pagina van onze site (op voorwaarde dat ze allemaal een veld 'titel' en 'invoer' hebben).
Merk op dat onze functie niets doet handvat de data; het werkt gewoon
als koerier, de informatie die we zoeken grijpen en doorgeven aan wat dan ook
komt daarna. Dit is belangrijk, want als het iets meer zou doen, zouden we in de
rijk van zakelijke logica.
Het korte antwoord is dat het voor de database zorgt
abstractie, wat in wezen betekent dat de gegevens kunnen worden gemigreerd vanuit MySQL
naar een andere database-indeling, zoals PostgreSQL of Oracle, allemaal zonder
wijzigen van de functies voor gegevensverwerking (bedrijfslaag), omdat de uitvoer dat zou doen
nog steeds gewoon een multidimensionale associatieve array zijn met ingangen met een
titel en ingangskolom, ongeacht het soort database dat we gebruiken.
Met de gegevens in onze array geladen, kunnen we beginnen met het verwerken van de informatie
geschikt voor onze doeleinden. In dit voorbeeld proberen we een invoervoorbeeld te maken. In
het eerste voorbeeld, de lengte van het voorbeeld was hard gecodeerd in de functie,
waarvan we hebben besloten dat het een slechte gewoonte is. In deze functie zullen we twee parameters doorgeven
naar onze code: de te verwerken tekst en het aantal woorden dat we willen weergeven
onze preview.
Laten we beginnen met te kijken naar de functie:
functie createTextPreview ($ text, $ length = 25) / * * Breek de tekst uit elkaar op de spaties en maak de voorbeeldvariabele * / $ words = explode (", $ text); $ preview = NULL; / * * Run a loop om woorden toe te voegen aan de voorbeeldvariabele * / 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;
In de bovenstaande functie controleren we eenvoudig dat het aantal woorden in de geleverde
invoer is groter dan het aantal woorden dat we in ons voorbeeld willen weergeven
voeg woorden één voor één toe aan de nieuw gemaakte $ previewvariabele totdat we onze hit hebben
doellengte, op welk moment we een ellips toevoegen en $ preview retourneren.
Net als in onze databaselaag houden we de code binnen de grenzen van de
bedrijfslaag. Het enige wat we doen is een tekstvoorbeeld maken; er is geen
interactie met de database en geen presentatie-elementen zoals HTML
markup.
Ten slotte moeten we de gegevens weergeven die we hebben opgehaald en verwerkt. Voor onze
doeleinden, we zullen het weergeven met extreem eenvoudige HTML-markeringen:
Het idee achter deze code is simpel: laad eerst de items met behulp van onze
databasefunctie, loop vervolgens door de vermeldingen, verkort de invoertekst
met behulp van onze preview-functie en vervolgens de titel en het invoervoorbeeld erin plaatsen
presentatie opmaak.
Nu, om de lay-out van de itemvoorbeelden te veranderen, zijn er slechts twee regels van
HTML moet worden aangepast. Dit is heel wat minder verwarrend dan het origineel
functie die alle drie lagen heeft afgehandeld.
Ik wil erop wijzen dat het bovenstaande voorbeeld erg eenvoudig is en alleen bedoeld is voor
demonstreren het concept van gelaagde programmering. Het idee is dat door het houden van de
verschillende typen programmeerlogica gescheiden, kunt u de hoeveelheid enorm vergroten
leesbaarheid en onderhoudbaarheid van uw code.
OPMERKING: Er is een geweldig artikel
op TheDailyWTF.com waarin het gebruik en misbruik van gelaagd softwareontwerp wordt besproken, en
prachtig commentaar op de
artikel met verschillende meningen. Multi-tiered applicaties zijn extreem handig, maar ook gemakkelijk te gebruiken
verkeerd begrijpen en te gecompliceerd maken, dus onthoud om uw software grondig te plannen voordat u bouwt om te voorkomen dat deze veroorzaakt
meer problemen dan je aan het oplossen bent.
Heb je enige gedachten over gelaagde applicaties? Welke stappen onderneemt u?
maximaal onderhoud en toekomstige wijzigingen in de code die u schrijft maximaliseren? Laat ons
weet in de reacties!