Objektorienterad autoladdning i WordPress, del 1

Jag har nyligen packat upp en serie där jag täckte namnområden och autoloading i WordPress. Om du inte är bekant med någon av ovanstående villkor rekommenderar jag att du ser ut serien.

Vad du kan förvänta dig att lära dig är följande:

I den här serien ska vi titta på exakt vad PHP namnområden är, varför de är fördelaktiga och hur de ska användas. Då ska vi titta på hur man använder autoladdare för att automatiskt ladda de filer vi behöver utan att manuellt ladda dem i vår kod.

Under arbetet med serien, särskilt autoloaderens, kunde jag inte låta bli att identifiera ett antal kodluktar som introducerades när jag delade koden med dig.

Detta betyder inte att autoloader är dålig eller att den inte fungerar. Om du har laddat ner pluginet, kör det eller följt efter och skrivit din egen autoloader, så vet du det gör faktiskt arbete.

Men i en serie som fokuserar på namnområden - något som är en del av objektorienterad programmering - kunde jag inte låta bli att känna mig obekväm att lämna autoloadern i sitt slutliga tillstånd i slutet av serien.

Misstolk mig inte: Jag står fortfarande vid serien, vad som var täckt och slutresultatet av det vi producerade. Men från en objektorienterad synpunkt finns det mer arbete som kan göras. Så i den här uppföljningsserien kommer vi att se över begreppet autoloaders ur objektorienterad programmering.

Specifikt kommer vi att prata om begreppet:

  • gränssnitt
  • gränssnitt implementering
  • principen om enansvar
  • och andra principer och idéer som är kärnan till objektorienterad programmering

Det är mitt hopp att vi, när vi slutför den här serien, inte bara har refactored vår autoloader till något som är mer underhållbart och lättare att läsa, men att det också följer större objektorienterade metoder.

Med det sagt, låt oss börja.

Komma igång

Som med nästan varje inlägg jag skriver, tycker jag om att försöka göra två saker:

  1. Definiera en färdplan där vi ska åka.
  2. Ge dig allt du behöver veta för att få din maskin igång.

Innan vi hoppar in på någon kod, låt oss göra det nu. 

Vår färdplan

Under de kommande två inläggen ska vi titta på några objektorienterade koncept som gör att vi kan förbättra det plugin som vi byggde i tidigare serier. 

Om du inte har en kopia av det insticksprogrammet kan du ladda ner en kopia av det. Jag delar emellertid fullständiga kodexemplar, kommentarer och förklaringar under varje handledning. 

Serien kommer att anta att du vet ingenting om något av de begrepp som vi kommer att diskutera så börjar vi från grunden. Allt du behöver är att ha tillräckligt med programvara på din maskin för att få en kopia av WordPress igång, och en redigerare där du kan redigera kod.

Vad du behöver

För att komma igång behöver du följande verktyg:

  • En lokal utvecklingsmiljö som inkluderar åtminstone PHP 5.6.20, Apache webbservern och en MySQL databas server. MAMP 4 är perfekt för detta.
  • En katalog där WordPress 4.6.1 är värd.
  • En textredigerare eller IDE av ditt val som du är bekväm med att använda för att skriva ett plugin.
  • En fungerande kunskap om WordPress Plugin API.

När du har allt det på plats (och jag vet att det verkar som mycket, men det tar inte lång tid att installera), måste du installera en kopia av plugin som är länkat ovan.

När vi är färdiga, är vi redo att börja prata om gränssnitt och principen om ensam ansvar.

Gränssnitt Definierat

Beroende på bakgrunden i programvaran kan du kanske tänka på vad användaren faktiskt ser på skärmen när du hör ordet "gränssnitt". Du vet: Ett användargränssnitt.

Men när det gäller objektorienterad design är det inte vad vi pratar om alls. Istället pratar vi om ett klassgränssnitt. Och detta kan vanligtvis beskrivas som klassen och de offentliga metoderna som den utsätter för andra klasser för att kommunicera med den.

Finns det en mer formell definition? Säker. Wikipedia erbjuder en:

I databehandling är ett gränssnitt en gemensam gräns över vilka två separata komponenter i ett datorsystem utbyter information.

Det här är inte så illa, faktiskt. Det är generellt nog att tillämpa på nästan vilket programmeringsspråk som helst, och det är det inte  Tekniskt att vi inte kan förstå det.

Då jobbar vi igen med PHP. Så vad har PHP-manualen att erbjuda på ämnet?

Objektgränssnitt gör det möjligt att skapa kod som anger vilka metoder en klass måste implementera, utan att behöva definiera hur dessa metoder hanteras.

Enligt min mening är detta en riktigt bra definition. Det är enkelt. Det är språk agnostic (till min vetskap), och det fungerar bra över de flesta (om inte alla) objektorienterade språk. Handboken säger till och med att säga:

Gränssnitt definieras på samma sätt som en klass, men med gränssnitt sökord som ersätter klass sökord och utan någon av metoderna som har innehållet definierat.
Alla metoder som deklareras i ett gränssnitt måste vara offentliga. Det här är en gränsens natur.

Det här är två punkter som vi måste kom ihåg om vi ska implementera våra egna gränssnitt, särskilt när det gäller det här plugin. Namnlösa: Vi måste komma ihåg följande:

  1. Vi definierar ett gränssnitt som om vi gör en klass, men vi använder gränssnitt nyckelord.
  2. De metoder som definieras i ett gränssnitt har allmänheten (i motsats till att vara skyddad eller privat) eftersom det här är det som garanterar funktionaliteten som andra klasser kan komma åt.

Innan vi går längre kan vi se hur ett gränssnitt i ett WordPress-projekt ser ut? Här är ett exempel från ett projekt jag har arbetat med:

Koden ovan borde vara tydlig med avseende på vilket syfte den tjänar, särskilt med tanke på kommentaren som sitter ovanför gränssnittet.

Som vi alla vet kan WordPress registrera och skriva in två typer av tillgångar: stylesheets och JavaScript-filer.

Eftersom båda dessa är tillgångar, skulle det vara motiverat att när vi skapar klasser för stylesheet management eller JavaScript-hantering, skulle vi generalisera det som ett tillgångar gränssnitt, rätt?

Vidare vet vi att vi vill initiera filen med hjälp av en init-metod så att vi kan koppla den angivna enqueue-funktionen till den korrekta WordPress API-funktionen. Alternativt kan det finnas något annat arbete du vill göra, och om så är fallet kanske du vill lägga till en annan metod signatur i gränssnittet.

Vad som än är fallet, vilken klass som implementerar detta gränssnitt måste tillhandahålla funktionalitet för följande metoder. Så vad skulle en klass som implementerar detta gränssnitt se ut?

Här är ett mycket enkelt exempel på en klass som lägger till stilark till administrationsområdet för WordPress:

Nu på vilket sätt Detta är instantierat och verkställt via PHP ligger utanför omfattningen av denna handledning. Vi ser det mycket när vi börjar refactoring vår autoloader. 

Men den punkt jag försöker visa är att ett gränssnitt definierar de offentliga metoder som en klass måste genomföra. Det definierar inte genomförandet, men det garanterar att en viss uppsättning funktioner kommer att finnas och är offentligt tillgängliga för tredjepartsklasser.

Principen om ensam ansvar

En av utmaningarna att prata om principen om enhetsansvar är att det ofta har missförstått att menar något som:

En klass (eller funktion eller rutin) ska göra en och en sak.

Men det är lite missvisat, eller hur? Jag menar även att en enkel för loop gör mer än en sak: Den initialiserar ett värde, jämförs med värden, och detter sedan värdet när loopens kropp är komplett.

Istället anger principen följande:

En klass bör bara ha en anledning att ändra.

Eftersom så många av oss utvecklar utnyttjar Google för att hjälpa oss i vårt dagliga arbete, tycker jag att det är viktigt att förstå källan till den här idén. Det här kommer från onkel Bob Martin, som han är känt, eller Robert Martin, som har författat ett antal programmeringsböcker på toppshylla.

Idén om att en klass som bara har en anledning att förändra bär med sig en hel del konsekvenser, eller hur? Här är ett exempel som kommer från vår autoloader som det står idag.

Låt oss granska koden (och jag vet att det inte är en klass, det är en funktion, men principen är tillämplig):

 0; $ i--) // Läs nuvarande komponent i fildelen. $ current = strtolower ($ file_parts [$ i]); $ current = str_ireplace ('_', '-', $ current); // Om vi ​​är vid första posten, så är vi på filnamnet. om (count ($ file_parts) - 1 === $ i) / * Om "gränssnitt" finns i delarna av filnamnet, ange sedan $ filnamnet på annat sätt så att det är korrekt laddat. * Annars, sätt bara $ filnamnet lika med klassen * filnamnstruktur. * / if (strpos (strtolower ($ file_parts [count ($ file_parts) - 1]), "gränssnitt")) // Ta gränsens namn från sitt kvalificerade namn. $ interface_name = explodera ('_', $ file_parts [count ($ file_parts) - 1]); $ interface_name = $ interface_name [0]; $ file_name = "interface- $ interface_name.php";  else $ file_name = "class- $ current.php";  annat $ namespace = '/'. $ nuvarande. $ Namespace;  // Skapa nu en sökväg till filen med kartläggning till filens plats. $ filepath = trailingslashit (dirname (dirname (__FILE__)). $ namespace); $ filepath. = $ filnamn; // Om filen finns i den angivna sökvägen, ta med den. om (file_exists ($ filepath)) include_once ($ filepath);  else wp_die (esc_html ("Filen som försöker laddas till $ filepath existerar inte."));  

Det finns mycket av saker som händer inom denna funktion. Bara titta på det från en hög nivå, vi kan se att det gör följande:

  • Det bestämmer om PHP försöker åberopa koden i den här funktionen.
  • Funktionen bestämmer om vi laddar ett gränssnitt eller en klass.
  • Autoloader försöker sedan att inkludera filen eller det tar ett fel.

Om en klass bara har en anledning att ändra, finns det tre skäl ovan (och det är bara på en hög nivå) där denna enda funktion kan förändras. Dessutom skulle koden kunna vara tydligare också.

Jag är inte en att blyga bort från kodkommentarer, men det finns mycket förklaring som händer i koden ovan. Och det är bra när du precis börjat skriva en autoloader, men när du är på väg till ett mer avancerat område som vi är, kommer det inte att hålla upp till mer rigorösa arkitekturer.

Hämta de två tillsammans

Det är här gränssnitten och principen om ansvar för enskilda ansvarsområden kan komma att fungera hand i hand.

Precis som ett gränssnitt ger en uppsättning funktionssignaturer (eller ett kontrakt) för vad dess implementatörer kommer att tillhandahålla, kan det se till att vilken klass som implementerar det gränssnittet strikt följer vad det definierar.

Men detta väcker en intressant fråga: Ska vi ha flera gränssnitt? Och svaret är att det beror på vilken typ av lösning du försöker skapa. 

I vårt fall tycker jag att det är vettigt. 

Vi vill trots allt undersöka ett inkommande klassnamn och bestämma om det är ett gränssnitt eller en klass, eller om det förtjänar att kasta ett fel. Dessutom ser vi till att den korrekta filen ingår med resten av systemet.

Men det är bortom ämnet för denna speciella handledning och en vi kommer att behöva utforska mer djup när det kommer dags att skriva mer kod.

Slutsats

Vid denna tidpunkt har vi täckt de nödvändiga koncepten så att vi kan börja refactoring vår autoloader. Det innebär att vi ska införa ett gränssnitt, se till att vår kod följer den, och så ska vi se till att vår klass (eller klasser) och deras respektive metoder följer principen om enhetsansvar.

Dessutom ser vi till att det fortsätter att fungera bra inom ramen för plugin, det är korrekt dokumenterat och att det följer WordPress-kodningsstandarderna.

Under tiden, om du är intresserad av att läsa mer om objektorienterad programmering i samband med WordPress, kan du hitta alla mina tidigare handledning på min profilsida. Gärna följa med mig på min blogg eller följ mig på Twitter där jag ofta pratar om båda.

Som alltid, om du letar efter andra verktyg för att hjälpa dig att bygga ut din växande uppsättning verktyg för WordPress eller till exempel kod för att studera och bli mer välbevandrad i WordPress, glöm inte att se vad vi har tillgängliga på Envato Market.

Med det sagt kommer nästa handledning i serien att bli betydligt mer praktisk. Det betyder att vi ska skriva kod, refactoring befintlig kod och tillämpa allt vi har lärt oss i den här handledningen. Tillså tveka inte att lämna någon feedback i kommentarerna.

Medel

  • Namespace och Autoloader Plugin
  • namnrymder
  • självladdande
  • gränssnitt
  • WordPress Plugin API
  • MAMP 4
  • Principen om ensam ansvar