Objektorientert autolading i WordPress, del 1

Jeg har nylig pakket inn en serie der jeg dekket navnerom og autoloading i WordPress. Hvis du ikke er kjent med de ovennevnte vilkårene, anbefaler jeg at du sjekker ut serien.

Kjernen til det du kan forvente å lære er som følger:

I denne serien skal vi se nærmere på hva PHP navneområder er, hvorfor de er fordelaktige, og hvordan de skal brukes. Deretter skal vi se på hvordan du bruker autoladere til å laste inn filene automatisk uten at du må laste dem manuelt i vår kode.

Mens jeg jobbet med serien, spesielt autoloaderens, kunne jeg ikke hjelpe, men gjenkjenne en rekke kode lukter som ble introdusert ettersom jeg delte koden med deg.

Dette er ikke å si at autoloader er dårlig eller at det ikke fungerer. Hvis du har lastet ned pluginet, kjører det, eller fulgt etter og skrevet din egen autoloader, så vet du det gjør faktisk arbeid.

Men i en serie som fokuserer på navneområder - noe som er en del av objektorientert programmering - kunne jeg ikke unngå å føle meg ubehagelig å forlate autoloaderen i sin endelige tilstand i slutten av serien.

Ikke misforstå meg: Jeg står fremdeles i serien, hva som var dekket, og sluttresultatet av det vi produserte. Men fra et objektorientert synspunkt er det mer arbeid som kan gjøres. Så i denne oppfølgingsserien skal vi revidere begrepet autoloaders fra et objektorientert programmerings perspektiv.

Spesielt skal vi snakke om konseptet om:

  • grensesnitt
  • grensesnitt implementering
  • det enkeltansvarlige prinsippet
  • og andre prinsipper og ideer som er kjernen til objektorientert programmering

Det er mitt håp at når vi fullfører denne serien, vil vi ikke bare ha refactored vår autoloader til noe som er mer vedlikeholdbart og lettere å lese, men at det også overholder større objektorientert praksis.

Med det sagt, la oss komme i gang.

Starter

Som med nesten alle innlegg jeg skriver, liker jeg å prøve å gjøre to ting:

  1. Definer en veikart av hvor vi skal hen.
  2. Gi deg alt du trenger å vite for å få maskinen i gang.

Før vi hopper på å skrive noen kode, la oss gjøre det nå. 

Vår veikart

I løpet av de neste to innleggene skal vi se på noen objektorienterte konsepter som skal tillate oss å forbedre på pluginet som vi bygde i forrige serie. 

Hvis du ikke har en kopi av det aktuelle pluginet, kan du laste ned en kopi av det, Jeg vil imidlertid dele komplekse eksempler, kommentarer og forklaringer i løpet av hver veiledning. 

Serien kommer til å anta at du vet ingenting om noen av konseptene som vi skal diskutere, så starter vi fra grunnen opp. Alt du trenger er å ha nok programvare på maskinen din for å få en kopi av WordPress oppe og kjører, og en editor der du kan redigere kode.

Hva trenger du

For å komme i gang, trenger du følgende verktøy:

  • Et lokalt utviklingsmiljø som inkluderer i det minste PHP 5.6.20, Apache webserveren og en MySQL databaseserver. MAMP 4 er perfekt for dette.
  • En katalog ut av hvilken WordPress 4.6.1 er vert.
  • En tekstredigerer eller IDE etter eget valg som du er komfortabel med å bruke til å skrive et plugin.
  • Et arbeidskunnskap om WordPress Plugin API.

Etter at du har alt det på plass (og jeg vet det virker som mye, men det tar ikke lang tid å sette opp), må du installere en kopi av pluginet som er koblet over.

Når vi er ferdige, er vi klare til å begynne å snakke om grensesnitt og prinsippet om enkeltansvar.

Grensesnitt Definert

Avhengig av bakgrunnen i programvare, når du hører ordet "grensesnitt", kan du ende opp med å tenke på hva brukeren faktisk ser på skjermen. Du vet: Et brukergrensesnitt.

Men når det gjelder objektorientert design, er det ikke det vi snakker om i det hele tatt. I stedet snakker vi om et klassegrensesnitt. Og dette kan vanligvis beskrives som klassen og de offentlige metodene det eksponerer for andre klasser for å kommunisere med den.

Er det en mer formell definisjon? Sikker. Wikipedia tilbyr en:

I databehandling er et grensesnitt en felles grense over hvilke to separate komponenter i et datasystem utveksler informasjon.

Dette er ikke så ille, faktisk. Det er generelt nok å søke på nesten hvilket som helst programmeringsspråk, og det er det ikke  teknisk at vi ikke kan forstå det.

Så igjen jobber vi med PHP. Så hva har PHP manualen å tilby på emnet?

Objektgrensesnitt lar deg lage kode som spesifiserer hvilke metoder en klasse må implementere, uten å måtte definere hvordan disse metodene håndteres.

Etter min mening er dette en veldig god definisjon. Det er enkelt. Det er språk agnostisk (til min kunnskap), og det fungerer bra på de fleste (om ikke alle) objektorienterte språk. Håndboken fortsetter å si:

Grensesnitt er definert på samme måte som en klasse, men med grensesnitt søkeord erstatter klasse søkeord og uten noen av metodene som har innholdet definert.
Alle metoder som er oppgitt i et grensesnitt, må være offentlige; Dette er naturen til et grensesnitt.

Dette er to poeng som vi  Husk om vi skal implementere våre egne grensesnitt, spesielt når det gjelder denne plugin. Nemlig må vi huske følgende:

  1. Vi definerer et grensesnitt mye som om vi gjør en klasse, men vi bruker grensesnitt søkeord.
  2. Metodene som er definert i et grensesnitt, har for publikum (i motsetning til å være beskyttet eller privat) fordi dette er det som garanterer funksjonaliteten som andre klasser kan få tilgang til.

Før vi går videre, hva kan et grensesnitt i et WordPress-prosjekt se ut? Her er et eksempel fra et prosjekt jeg har jobbet med:

Koden ovenfor skal være tydelig med hensyn til hvilken hensikt den tjener, spesielt gitt kommentaren som sitter over grensesnittet.

Som vi alle vet, kan WordPress registrere og kreve to typer eiendeler: stilark og JavaScript-filer.

Siden begge disse er eiendeler, vil det være grunn til at når vi lager klasser for stilarkstyring eller JavaScript-administrasjon, vil vi generalisere det som et grensesnitt for eiendeler, til høyre?

Videre vet vi at vi vil initialisere filen ved hjelp av en init-metode slik at vi kan hekte den angitte enqueue-funksjonen til riktig WordPress API-funksjon. Alternativt kan det være noe annet arbeid du vil gjøre, og hvis det er tilfelle, vil du kanskje legge til en annen metode signatur til grensesnittet.

Uansett hva som helst, hvilken som helst klasse som implementerer dette grensesnittet  gi funksjonalitet for følgende metoder. Så hva ville en klasse som implementerer dette grensesnittet se ut?

Her er et veldig enkelt eksempel på en klasse som legger til stilark til administrasjonsområdet for WordPress:

Nå hvordan Dette er instantiated og håndhevet via PHP er utenfor omfanget av denne opplæringen. Vi ser det rikelig når vi begynner å refactoring vår autoloader. 

Men poenget jeg prøver å vise er at et grensesnitt definerer de offentlige metodene en klasse må implementere. Det definerer ikke implementeringen, men det garanterer at et bestemt sett av funksjoner vil eksistere og er offentlig tilgjengelig for tredjepartsklasser.

Prinsippet om enkelt ansvar

En av utfordringene ved å snakke om prinsippet om enkeltansvar er at det ofte er misforstått å bety noe som:

En klasse (eller funksjon eller rutine) bør gjøre en og en ting.

Men det er litt misforstått, ikke sant? Jeg mener at selv en enkel for sløyfe gjør mer enn én ting: Den initialiserer en verdi, sammenligner med verdier, og detter deretter verdien når sløyfens kropp er fullført.

I stedet oppgir prinsippet følgende:

En klasse skal bare ha en grunn til å forandre seg.

Fordi så mange av oss utviklere bruker Google til å hjelpe oss i det daglige arbeidet, tror jeg det er viktig å forstå kilden til denne ideen. Det vil si, dette kom fra onkel Bob Martin, som han er tilfeldig kjent, eller Robert Martin, som har skrevet en rekke hylle programmeringsbøker.

Ideen om at en klasse har bare en grunn til å forandre, bærer med seg en hel rekke implikasjoner, ikke sant? Her er et eksempel som kommer opp i tankene fra vår autoloader som det står i dag.

La oss se på koden (og jeg vet at det ikke er en klasse, det er en funksjon, men prinsippet gjelder):

 0; $ i--) // Les den nåværende delen av fildelen. $ current = strtolower ($ file_parts [$ i]); $ current = str_ireplace ('_', '-', $ current); // Hvis vi er ved første oppføring, så er vi på filnavnet. hvis (telle ($ file_parts) - 1 === $ i) / * Hvis "grensesnitt" er inkludert i delene av filnavnet, så * definer $ filnavn på en annen måte slik at den er riktig lastet inn. * Ellers må du bare sette $ filnavn samme som klassen * filnavn struktur. * / hvis (strpos (strtolower ($ file_parts [count ($ file_parts) - 1]), 'grensesnitt')) // Grab navnet på grensesnittet fra sitt kvalifiserte navn. $ interface_name = explode ('_', $ file_parts [count ($ file_parts) - 1]); $ interface_name = $ interface_name [0]; $ file_name = "interface- $ interface_name.php";  ellers $ file_name = "class- $ current.php";  ellers $ namespace = '/'. $ nåværende. $ Namespace;  // Nå bygger du en bane til filen ved hjelp av kartlegging til filplasseringen. $ filepath = trailingslashit (dirname (dirname (__FILE__)). $ namespace); $ filepath. = $ filnavn; // Hvis filen finnes i den angitte banen, så inkluder den. hvis (file_exists ($ filepath)) include_once ($ filepath);  else wp_die (esc_html ("Filen som forsøker å bli lastet inn på $ filepath eksisterer ikke."));  

Det er mye av ting som skjer i denne funksjonen. Bare se på det fra et høyt nivå, vi kan se at det gjør følgende:

  • Det avgjør om PHP prøver å påkalle koden i denne funksjonen.
  • Funksjonen bestemmer om vi laster inn et grensesnitt eller en klasse.
  • Autoloaderen forsøker da å inkludere filen eller det kaster en feil.

Hvis en klasse bare skal ha en grunn til å forandre, er det tre grunner ovenfor (og det er bare på et høyt nivå) hvor denne enkeltfunksjonen kan endres. Videre kan koden også være klarere.

Jeg er ikke en til å vike bort fra kodekommentarer, men det skjer mye forklaring i koden ovenfor. Og det er greit når du bare begynner å skrive en autoloader, men når du er på vei inn i mer avansert territorium som vi er, vil det ikke holde opp til strengere arkitekturer.

Ta med to sammen

Dette er hvor grensesnitt og enkeltansvarsprinsippet kan komme til å arbeide hånd i hånd.

Akkurat som et grensesnitt gir et sett med funksjons signaturer (eller en kontrakt) for hva dens implementatører vil gi, kan det sikre at enhver klasse som implementerer dette grensesnittet, overholder strengt hva det definerer.

Men dette reiser et interessant spørsmål: Skal vi ha flere grensesnitt? Og svaret er at det avhenger av arten av løsningen du prøver å skape. 

I vårt tilfelle synes jeg det er fornuftig. 

Tross alt ser vi ut til å undersøke et innkommende klassenavn og avgjøre om det er et grensesnitt eller en klasse, eller hvis det fortjener å kaste en feil. Videre ser vi til å sikre at den riktige filen er inkludert med resten av systemet.

Men det er utenfor emnet for denne spesielle opplæringen, og vi må utforske nærmere når det kommer tid til å skrive mer kode.

Konklusjon

På dette tidspunktet har vi dekket de nødvendige konseptene slik at vi kan begynne å refactoring vår autoloader. Det vil si at vi skal introdusere et grensesnitt, sørge for at vår kode overholder den, og så sørger vi for at vår klasse (eller klasser) og deres respektive metoder overholder prinsippet om enkeltansvar.

Videre vil vi sørge for at det fortsetter å fungere godt innenfor rammen av plugin, det er riktig dokumentert, og at det følger WordPress Coding Standards.

I mellomtiden, hvis du er interessert i å lese mer om objektorientert programmering i sammenheng med WordPress, kan du finne alle mine tidligere opplæringsprogrammer på min profilside. Følg med på bloggen min eller følg meg på Twitter der jeg ofte snakker om begge.

Som alltid, hvis du leter etter andre verktøy for å hjelpe deg med å bygge ut ditt voksende sett med verktøy for WordPress eller for eksempel kode for å studere og bli mer kjent med WordPress, ikke glem å se hva vi har tilgjengelig i Envato Market.

Med det sagt, vil neste opplæring i serien bli langt mer praktisk. Det vil si at vi skal skrive kode, refactoring eksisterende kode, og bruke alt vi har lært i denne opplæringen. Inntil da, ikke nøl med å legge igjen tilbakemelding i kommentarene.

ressurser

  • Namespace og Autoloader Plugin
  • navnerom
  • autoloading
  • grensesnitt
  • WordPress Plugin API
  • MAMP 4
  • Enkelt ansvar prinsipp