Obiect-Oriented Autoloading în WordPress, Partea 1

Am încheiat recent o serie în care am acoperit spațiile de nume și autoloading în WordPress. Dacă nu sunteți familiarizat cu nici unul din termenii de mai sus, atunci vă recomandăm să verificați seria.

Conținutul de ceea ce vă puteți aștepta să învețiți este după cum urmează:

În această serie, vom examina exact ce spații de nume PHP sunt, de ce sunt benefice și cum să le folosiți. Apoi, vom analiza modul de utilizare a autoloader-urilor pentru a încărca automat fișierele de care avem nevoie fără a trebui să le încărcați manual în codul.

În timp ce lucram la serie, în special la autoloader, nu am reușit să recunosc un număr de mirosuri de cod care erau introduse pe măsură ce îmi împărțeam codul.

Aceasta nu înseamnă că autoloaderul este rău sau că nu funcționează. Dacă ați descărcat plugin-ul, rulați-l sau urmați-l și scrieți-vă propriul autoloader, atunci știi asta face de fapt munca.

Dar într-o serie care se axează pe spațiile de nume - ceva ce face parte integrantă din programarea orientată pe obiecte - nu am putut să mă simt incomod, lăsând autoloader-ul în starea finală la sfârșitul seriilor.

Nu mă întrebați greșit: mă aflu încă în seriile, ceea ce a fost acoperit și rezultatul final al ceea ce am produs. Dar dintr-un punct de vedere orientat spre obiecte, există mai mult de lucru care se poate face. Deci, în această serie de follow-up, vom relua conceptul de autoloaders din perspectiva programării orientate obiect.

Mai exact, vom vorbi despre conceptul de:

  • interfețe
  • implementarea interfeței
  • principiul responsabilității unice
  • și alte principii și idei care sunt esențiale pentru programarea orientată-obiect

Sper că sperăm că, odată cu finalizarea acestei serii, nu numai că am redactat autoloaderul nostru în ceva mai ușor de întreținut și mai ușor de citit, dar și că aderă la practici mai orientate spre obiect.

Cu asta a spus, să începem.

Noțiuni de bază

Ca și în aproape fiecare post pe care îl scriu, îmi place să încerc să fac două lucruri:

  1. Definiți o foaie de parcurs pentru locul în care mergem.
  2. Dați-vă tot ce trebuie să știți pentru a vă pune mașina în funcțiune.

Înainte de a începe să scriem orice cod, să facem asta acum. 

Foaia de parcurs

În următoarele două postări, vom examina câteva concepte orientate pe obiecte care ne vor permite să îmbunătățim pluginul pe care l-am construit în seria anterioară. 

Dacă nu aveți o copie a pluginului, puteți descărca o copie a acestuia; cu toate acestea, voi distribui exemple complete de cod, comentarii și explicații în fiecare tutorial. 

Seria va presupune că știți nimic despre oricare dintre conceptele pe care le vom discuta, așa că vom începe de la început. Tot ce aveți nevoie este să aveți suficiente programe software pe mașina dvs. pentru a obține o copie a programului WordPress în funcțiune și un editor în care puteți edita codul.

De ce ai nevoie

Pentru a începe, veți avea nevoie de următoarele instrumente:

  • Un mediu de dezvoltare locală care include macar PHP 5.6.20, serverul web Apache și un server de baze de date MySQL. MAMP 4 este perfect pentru acest lucru.
  • Un director din care WordPress 4.6.1 este găzduit.
  • Un editor de text sau un IDE la alegerea dvs., pe care îl utilizați pentru scrierea unui plugin.
  • O cunoaștere activă a API-ului WordPress Plugin.

După ce aveți toate acestea în loc (și știu că pare o mulțime, dar într-adevăr nu este nevoie de mult timp pentru a configura), va trebui să instalați o copie a plugin-ului conectat mai sus.

După ce ați terminat, suntem gata să începem să vorbim despre interfețe și principiul responsabilității unice.

Interfețe definite

În funcție de fundalul dvs. în software, atunci când auziți cuvântul "interfață", este posibil să vă gândiți la ceea ce văd efectiv pe ecran. Știi: o interfață cu utilizatorul.

Dar când vine vorba de design-ul orientat pe obiect, nu despre asta vorbim deloc. În schimb, vorbim de o interfață de clasă. Și aceasta poate fi descrisă, de obicei, ca clasă și metodele publice pe care le expune pentru alte clase să comunice cu ea.

Există o definiție mai formală? Sigur. Wikipedia oferă una:

În calcul, o interfață este o limită comună în care două componente separate ale unui sistem informatic schimbă informații.

Nu e așa de rău, de fapt. Este destul de general să se aplice aproape oricărui limbaj de programare, și nu este asa de tehnice pe care nu le putem înțelege.

Apoi, din nou, lucrăm cu PHP. Deci, ceea ce manualul PHP are de oferit pe această temă?

Interfețele de obiecte vă permit să creați un cod care să specifice metodele pe care o clasă trebuie să le implementeze, fără a fi nevoie să definiți modul în care sunt gestionate aceste metode.

În opinia mea, aceasta este o definiție foarte bună. E simplu. Este limbaj agnostic (după cunoștințele mele) și funcționează bine în majoritatea limbilor orientate pe obiecte (dacă nu toate). Manualul continuă chiar să spună:

Interfețele sunt definite în același mod ca și clasa, dar cu interfață cuvinte cheie înlocuind clasă cuvânt cheie și fără nici o metodă cu conținutul lor definit.
Toate metodele declarate într-o interfață trebuie să fie publice; aceasta este natura unei interfețe.

Acestea sunt două puncte pe care noi trebuie sa amintiți-vă dacă vom implementa propriile interfețe, mai ales când vine vorba de acest plugin. Mai precis, trebuie să ne amintim următoarele:

  1. Definim o interfață la fel ca și noi, dar folosim interfață cuvinte cheie.
  2. Metodele definite într-o interfață au pentru public (spre deosebire de a fi protejat sau privat) deoarece acest lucru garantează funcționalitatea pe care o pot accesa alte clase.

Înainte de a merge mai departe, ar putea arăta o interfață într-un proiect WordPress? Iată un exemplu dintr-un proiect pe care lucram:

Codul de mai sus ar trebui să fie clar în ce scop servește, mai ales având în vedere comentariul care stă deasupra interfeței.

După cum știm cu toții, WordPress poate înregistra și încorpora două tipuri de active: fișiere de stil și fișiere JavaScript.

Din moment ce ambele sunt active, atunci ar rezida la raționamentul că, atunci când creăm clase pentru gestionarea stilului de șabloane sau gestionarea JavaScript, îl generalizăm ca o interfață de active, drept?

Mai mult, știm că vrem să inițializăm fișierul utilizând o metodă init, astfel încât să putem atașa funcția enqueue specificată la funcția corectă API WordPress. În mod alternativ, poate exista o altă lucrare pe care ați dori să o faceți și, dacă este cazul, atunci este posibil să doriți să adăugați altă semnătură de metodă la interfață.

Indiferent de situație, orice clasă care implementează această interfață trebuie sa asigură funcționalitatea pentru următoarele metode. Deci, ce ar arăta o clasă care implementează această interfață?

Iată un exemplu foarte simplu de clasă care adaugă foi de stil spre zona de administrare a WordPress:

Acum Cum acest lucru este instanțiat și aplicat prin PHP este dincolo de scopul acestui tutorial. Vom vedea o mulțime când vom începe să refactorizăm autoloaderul nostru. 

Dar punctul pe care încerc să-l arăt este că o interfață definește metodele publice pe care o clasă trebuie să le implementeze. Nu definește implementarea, dar garantează existența unui anumit set de funcții și accesul public la clasele terțe.

Principiul unic responsabilitate

Una dintre provocările de a vorbi despre principiul responsabilității unice este că adesea a fost greșit înțeles să însemnem ceva de genul:

O clasă (sau o funcție sau o rutină) ar trebui să facă un singur lucru.

Dar asta e puțin greșit, nu-i așa? Vreau să spun chiar și o simplă pentru buclă are mai mult de un lucru: Inițializează o valoare, se compară cu valorile și apoi iterează valoarea când corpul bucla este complet.

În schimb, principiul prevede următoarele:

O clasă ar trebui să aibă doar un singur motiv pentru a se schimba.

Deoarece atât de mulți dintre noi, dezvoltatorii, îi ajutăm pe Google să ne ajute în munca noastră zilnică, cred că este important să înțelegem sursa acestei idei. Asta a venit de la unchiul Bob Martin, așa cum este cunoscut, sau Robert Martin, care a scris un număr de cărți de programare de top.

Ideea unei clase având doar un singur motiv de schimbare poartă cu ea o mulțime de implicații, nu-i așa? Iată un exemplu care vine în minte de la autoloaderul nostru, așa cum se află astăzi.

Să examinăm codul (și știu că nu este o clasă, este o funcție, dar principiul este aplicabil):

 0; $ i--) // Citiți componenta curentă a părții de fișier. $ curent = strtolower ($ file_parts [$ i]); $ curent = str_ireplace ('_', '-', $ curent); // Dacă suntem la prima intrare, atunci suntem la numele fișierului. dacă (numără ($ file_parts) - 1 === $ i) / * Dacă "interfața" este conținută în părțile din numele fișierului, atunci * definește $ file_name diferit, astfel încât să fie încărcat corect. * În caz contrar, trebuie doar să setați $ file_name egal cu cel al structurii de nume * filename *. * / if (strpos (strtolower ($ file_parts [count ($ file_parts) - 1]), 'interfață')) // Luați numele interfeței din numele său calificat. $ nume_intervenție = explode ('_', $ file_parts [count ($ file_parts) - 1]); $ interface_name = $ numele interfeței [0]; $ file_name = "interfață- $ nume_intervenție.php";  altceva $ file_name = "class- $ current.php";  altceva $ namespace = '/'. $ curent. Spațiu de nume $;  // Acum construi o cale către fișier folosind maparea în locația fișierului. $ filepath = trailingslashit (dirname (dirname (__FILE__)) $ namespace); $ filepath. = $ nume_fișier; // Dacă fișierul există în calea specificată, atunci includeți-l. dacă (file_exists ($ filepath)) include_once ($ filepath);  altceva wp_die (esc_html ("Fișierul care încearcă să fie încărcat la $ filepath nu există"));  

Există mult de lucruri care se întâmplă în cadrul acestei funcții. Privind la un nivel înalt, putem vedea că face următoarele:

  • Aceasta determină dacă PHP încearcă să invocă codul în această funcție.
  • Funcția determină dacă încărcăm o interfață sau o clasă.
  • Autoloaderul încearcă apoi să includă fișierul sau aruncă o eroare.

Dacă o clasă ar trebui să aibă doar un singur motiv pentru a se schimba, există trei motive mai sus (și asta este doar la un nivel înalt) la care această singură funcție s-ar putea schimba. Mai mult, codul ar putea fi mai clar.

Nu sunt unul care să se ferească de comentariile codului, dar în codul de mai sus există o mulțime de explicații. Și este bine când începeți să scrieți un autoloader, dar când vă îndreptați spre un teritoriu mai avansat, așa cum suntem noi, atunci acesta nu va rezista unor arhitecturi mai riguroase.

Aducerea celor doi împreună

Aici interfețele și principiul responsabilității unice pot ajunge la treabă.

Așa cum o interfață furnizează un set de semnături de funcții (sau un contract) pentru ceea ce furnizează implementatorii săi, se poate asigura că orice clasă care implementează această interfață aderă strict la ceea ce definește.

Dar aceasta ridică o întrebare interesantă: Ar trebui să avem mai multe interfețe? Iar răspunsul este că depinde de natura soluției pe care încercați să o creați. 

În cazul nostru, cred că are sens. 

La urma urmei, căutăm să examinăm un nume de clasă de intrare și să determinăm dacă este o interfață sau o clasă sau dacă merită să arunci o eroare. În plus, căutăm să asigurăm că fișierul corespunzător este inclus împreună cu restul sistemului.

Dar acest lucru este dincolo de subiectul acestui tutorial special și unul va trebui să explorăm în profunzime când vine vorba să scrieți mai multe coduri.

Concluzie

În acest moment, am acoperit conceptele necesare pentru a putea începe refactorizarea autoloaderului nostru. Adică vom introduce o interfață, asigurându-ne că codul nostru aderă la acesta și apoi ne vom asigura că clasa (sau clasele) și metodele respective respectă principiul responsabilității unice.

În plus, vom asigura că acesta continuă să funcționeze bine în contextul pluginului, este bine documentat și că respectă standardele de codificare WordPress.

Între timp, dacă sunteți interesat să citiți mai multe despre programarea orientată pe obiecte în contextul WordPress, puteți găsi toate tutorialele mele anterioare pe pagina mea de profil. Simțiți-vă liber să mă urmeze pe blogul meu sau să mă urmeze pe Twitter unde vorbesc frecvent despre ambele.

Ca întotdeauna, dacă sunteți în căutarea altor utilități pentru a vă ajuta să vă construiți un set în creștere de instrumente pentru WordPress sau, de exemplu, pentru a studia și a deveni mai bine versat în WordPress, nu uitați să vedeți ceea ce avem la dispoziție în piața Envato.

Cu asta a spus că următorul tutorial din serie va fi mult mai practic. Adică, vom scrie cod, vom refactoriza codul existent și vom aplica tot ceea ce am învățat în acest tutorial. Până atunci, nu ezitați să lăsați orice comentariu în comentarii.

Resurse

  • Spațiul de nume și pluginul Autoloader
  • Spații de nume
  • Autoîncărcarea
  • interfeţe
  • API-ul Plugin-ului WordPress
  • MAMP 4
  • Principiul unic de responsabilitate
Cod