In dem vorherigen Tutorial haben wir eine Handvoll Konzepte behandelt, die alle notwendig sein werden, um vollständig zu verstehen, was wir in diesem Tutorial tun.
Konkret behandelten wir die folgenden Themen:
In manchen Serien ist es einfach, Tutorials zu überspringen, die möglicherweise nicht aufeinander aufbauen. Diese Serie soll jedoch nicht so sein. Stattdessen ist es dazu gedacht, in sequentieller Reihenfolge gelesen zu werden, und es soll auf den Inhalt jedes vorherigen Tutorials aufbauen.
Ich nehme an, Sie sind alle auf dem Laufenden.
Auch wenn ich dies vielleicht im ersten Tutorial erwähnt habe, möchte ich trotzdem sicherstellen, dass wir alle auf der gleichen Seite sind, was wir in jedem Tutorial tun und welche Software Sie benötigen.
In diesem Lernprogramm sieht der Plan wie folgt aus:
Letztendlich werden wir nicht schreiben viel Code in diesem Tutorial, aber wir werden etwas schreiben. Es ist jedoch ein praktisches Tutorial, in dem wir objektorientierte Analyse und Design durchführen. Dies ist eine notwendige Phase für viele große Projekte (und etwas, das für kleine Projekte geschehen sollte)..
Wenn Sie mitverfolgt haben, sollten Sie dies bereits eingerichtet haben. Aber um sicher zu gehen, hier ist die kurze Version von allem, was Sie brauchen:
Wenn all dies vorhanden ist, können wir an dem Code arbeiten, der im vorherigen Tutorial verwendet wurde. Also lasst uns anfangen.
Als erstes wollen wir den aktuellen Zustand unseres Autoloaders analysieren. Es mag wie eine Menge Code aussehen, den Sie in einen einzelnen Codeblock einfügen können, aber das zeigt schon, dass wir noch einiges zu tun haben.
Hier ist der aktuelle Stand unseres Autoloaders:
0; $ i--) // Liest die aktuelle Komponente des Dateiteils. $ current = strtolower ($ file_parts [$ i]); $ current = str_ireplace ('_', '-', $ current); // Wenn wir beim ersten Eintrag sind, dann beim Dateinamen. if (count ($ file_parts) - 1 === $ i) / * Wenn 'interface' in den Teilen des Dateinamens enthalten ist, * definieren Sie den $ file_name anders, damit er ordnungsgemäß geladen wird. * Andernfalls setzen Sie einfach $ file_name auf die Struktur der Klasse * Dateiname. * / if (strpos (strtolower ($ file_parts [count ($ file_parts) - 1]), 'interface')) // Ergreifen Sie den Namen der Schnittstelle aus ihrem qualifizierten Namen. $ interface_name = explodieren ('_', $ file_parts [Anzahl ($ file_parts) - 1]); $ interface_name = $ interface_name [0]; $ file_name = "interface- $ interface_name.php"; else $ file_name = "class- $ current.php"; else $ namespace = '/'. $ current $ namespace; // Erstellen Sie nun einen Pfad zur Datei, indem Sie den Dateispeicherort zuordnen. $ filepath = trailingslashit (dirname (dirname (__FILE__)). $ namespace); $ filepath. = $ dateiname; // Wenn die Datei im angegebenen Pfad vorhanden ist, schließen Sie sie ein. if (file_exists ($ filepath)) include_once ($ filepath); else wp_die (esc_html ("Die Datei, die versucht, unter $ filepath geladen zu werden, ist nicht vorhanden."));
Denken Sie an dieser Stelle daran, dass das Prinzip der Einzelverantwortung Folgendes festlegt:
Eine Klasse sollte nur einen Grund haben, sich zu ändern.
Im Moment haben wir nicht einmal eine Klasse, geschweige denn mehrere einzelne Methoden, die nur einen einzigen Grund haben, um sie zu ändern.
Und obwohl es sinnvoll sein könnte, diese Autoloader-Methode in kleinere, einzelne Methoden zu zerlegen, beginnen wir auf einer höheren Ebene und denken über einen Autoloader in Bezug auf eine Schnittstelle nach. Dann werden wir einen Drilldown machen, um eine Klasse (oder Klassen) zu erstellen..
Erinnern Sie sich aus dem vorherigen Tutorial, dass eine Schnittstelle im PHP-Handbuch wie folgt definiert ist:
Mit Objektschnittstellen können Sie Code erstellen, der angibt, welche Methoden eine Klasse implementieren muss, ohne festzulegen, wie diese Methoden behandelt werden.
Lassen Sie uns angesichts des Codes und der obigen Definitionen darüber nachdenken, was ein Autoloader aus einer modularen Perspektive tun muss. Lassen Sie uns es in Punkte unterteilen, die repräsentieren, was möglicherweise genug ist, um sich zu ändern. Nein, wir können nicht alle diese Punkte verwenden, aber deshalb wird es Analyse genannt. Wir werden später am Entwurf arbeiten.
Der Code bewirkt Folgendes:
$ class_name
ist ein schlechter Variablenname).Der obige Code funktioniert also neun Dinge-das ist es wenigstens Neun Gründe zu ändern, bevor die Arbeit abgeschlossen ist.
Dies sollte selbstverständlich sein, aber diese besondere Funktion ist ein perfektes Beispiel, das wir umgestalten können, um objektorientierte Analyse, Design, Schnittstellen und Implementierung zu demonstrieren.
Und das wirft eine Frage auf: Wo fangen wir überhaupt an??
An diesem Punkt ist es fair zu sagen, dass wir mit der objektorientierten Analyse beginnen können. Das heißt, wir schauen uns an, welche potenziellen Klassen wir haben könnten und wie sie miteinander interagieren, wenn wir alles, was wir oben aufgelistet haben, zusammenbringen. Denken Sie daran, wir möchten auch, dass der Grundsatz der Einzelverantwortung uns bei der Entscheidungsfindung unterstützt.
An diesem Punkt sind wir nicht besonders besorgt darüber, wie die Klassen miteinander kommunizieren werden. Stattdessen konzentrieren wir uns mehr auf das Erstellen von Klassen, die aus einem einzigen Grund geändert werden müssen.
Nachdem dies gesagt wurde, werde ich ein Beispiel an Klassen anbieten, die meiner Meinung nach funktionieren könnten. Bevor Sie fortfahren, schauen Sie sich an, was wir getan haben und versuchen Sie, Ihre eigene Liste aufzustellen. Dann können wir Notizen vergleichen.
Beachten Sie, dass Sie möglicherweise eine bessere Idee haben als die unten aufgeführten, oder Sie nehmen etwas von dem, was wir geteilt haben. Unabhängig davon ist dies eine Lernübung. Wir versuchen, unseren Code und unsere Organisation zu verbessern und letztendlich bessere Programmierer zu werden.
In Anbetracht dessen, was ich oben aufgeführt habe, habe ich folgende Klassen gefunden:
Und das ist es. Jetzt müssen Drittanbieter-Klassen in unserem Plugin nur etwas über die Autoloader-Klasse wissen, aber der Autoloader benötigt Kenntnisse über eine andere Klasse und andere Klassen benötigen Kenntnisse über andere Klassen.
Dort sind Möglichkeiten, dies zu handhaben (mithilfe von Abhängigkeitseinspritzungscontainern, aber das würde den Rahmen dieses Projekts sprengen). Was wir jedoch mit unserem Code erreichen möchten, ist die Minimierung, wie viele Klassen voneinander wissen.
Zu diesem Zeitpunkt werden verschiedene Entwickler, Firmen, Agenturen und Teams einen anderen Ansatz wählen, wie sie das System entwerfen, an dem sie arbeiten.
Eine der gebräuchlichsten Methoden, dies zu tun, ist die Verwendung eines sogenannten UML-Diagramms. Obwohl es nützlich ist, lohnt es sich nicht, im Rahmen dieses Tutorials etwas zu tun, da es ein ganz anderes Tutorial erfordert, um alle Teile zu erklären.
Für die Zwecke unseres Tutorials und da wir mit so wenig Code arbeiten, versuchen wir herauszufinden, wie die einzelnen Klassen funktionieren können, bevor wir sie implementieren. Auf diese Weise erhalten wir eine Vorstellung davon, wie wir unseren Code organisieren können.
Beachten Sie, dass wir noch keinen Namensraum für diesen Code haben werden, und dieser Code sollte noch nicht mit WordPress implementiert oder getestet werden. Wir werden im nächsten Tutorial darauf eingehen.
Beginnen wir mit dem Autoloader
und von dort aus arbeiten.
Denken Sie daran, dass diese Klasse für die Aufnahme der erforderlichen Datei verantwortlich ist. Dies ist die Datei, die beim registriert wird spl_autoload_register
Funktion.
namespace_validator = neuer NamespaceValidator (); $ this-> file_registry = new FileRegistry (); öffentliche Funktion load ($ filename) if ($ this-> namespace_validator-> is_valid ($ filename)) $ this-> file_registry-> load ($ filename);
Beachten Sie, dass diese Klasse von der Klasse abhängt NamespaceValidator
und das FileRegistry
Klasse. Wir werden jeden von ihnen in einem Moment genauer betrachten.
Diese Datei prüft den eingehenden Dateinamen und ermittelt, ob er gültig ist. Dies geschieht durch Betrachten des Namespaces im Dateinamen.
Wenn die Datei tut In der Tat gehören wir zu unserem Namensraum, dann können wir davon ausgehen, dass es sicher ist, unsere Datei zu laden.
FileInvestigator
Diese Klasse macht ziemlich viel Arbeit, obwohl ein Teil davon mit sehr einfachen, sehr kleinen Hilfsmethoden durchgeführt wird. Im Verlauf der Ausführung wird der Typ der übergebenen Datei geprüft.
Anschließend wird der vollständig qualifizierte Dateiname für den Dateityp abgerufen.
get_file_name ($ file_parts, $ current, $ i); if (count ($ file_parts) - 1! == $ i) $ filepath = trailingslashit ($ filepath); return $ filepath; private Funktion get_file_name ($ file_parts, $ current, $ i) $ filename = "; if (count ($ file_parts) - 1 === $ i) if ($ this-> is_interface ($ file_parts)) $ Dateiname = $ this-> get_interface_name ($ file_parts); else $ dateiname = $ this-> get_class_name ($ current); else $ Dateiname = $ this-> get_namespace_name ($ current); return $ filename; private Funktion is_interface ($ file_parts) return strpos (strtolower ($ file_parts [Anzahl ($ file_parts) - 1]), 'interface'); private Funktion get_interface_name ($ file_parts) $ interface_name = explode ('_', $ file_parts [count ($ file_parts) - 1]); $ interface_name = $ interface_name [0]; return "interface- $ interface_name.php"; private Funktion get_class_name ($ current) return "class- $ current.php" ; private Funktion get_namespace_name ($ current) return '/'. $ current;Wenn es eine Datei gibt, die ein wenig mehr überarbeitet werden kann, dann ist dies die richtige. Schließlich versucht es festzustellen, ob wir mit einer Klasse, einem Interface oder einer Klasse arbeiten. Eine einfache Fabrik könnte dafür besser geeignet sein.
Wenn es an der Zeit ist, unseren Code zu implementieren, werden wir dies möglicherweise weiter überarbeiten. Bis dahin ist dies ein vorläufiger Entwurf, der gut genug funktionieren kann.
FileRegistry
Dabei wird der vollständig qualifizierte Dateipfad verwendet und die Datei eingeschlossen. Andernfalls wird die WordPress-API verwendet, um eine Fehlermeldung anzuzeigen.
Klasse FileRegistry privater $ investigator; öffentliche Funktion __construct () $ this-> investigator = new FileInvestigator (); public function load ($ filepath) $ filepath = $ this-> investigator-> get_filetype ($ filepath); $ filepath = rtrim (plugin_dir_path (dirname (__FILE__)), '/'). $ filepath; if (file_exists ($ filepath)) include_once ($ filepath); else wp_die (esc_html ('Die angegebene Datei ist nicht vorhanden.'));Eine andere Alternative zur Verwendung der WordPress-API wäre das Auslösen einer benutzerdefinierten Ausnahmemeldung. Auf diese Weise können wir unseren Code vollständig von WordPress trennen oder entkoppeln.
Dieser Code ist wieder eine Verschleppung vom ursprünglichen Autoloader. Während der Implementierung können wir dies auch ändern.
Fazit
In Ordnung, also haben wir uns den vorhandenen Code für unseren Autoloader angesehen, und dann haben wir einige potenzielle Codes verdrängt, die wir basierend auf objektorientierter Analyse und Design verwenden können.
Ist die Lösung, an der wir arbeiten, wartbarer als die, die wir haben? Absolut. Funktioniert dies im Kontext von WordPress und unserem vorhandenen Plugin? Wir werden es nicht wissen, bis wir damit beginnen, unser Plugin zu nutzen.
Wie bereits erwähnt, gibt es immer noch einige Bereiche, in denen wir diesen Code möglicherweise umgestalten könnten. Wenn wir bei der Implementierung unseres Codes in der endgültigen Version unseres Plugins auf diese Art von Problemen stoßen, schauen wir uns genau das an.
Wie auch immer, der Code, den wir jetzt haben, sollte besser lesbar sein (obwohl wir noch DocBlocks und einige Inline-Kommentare einführen müssen) und wartungsfreundlicher und sogar noch testbarer.
Ich hoffe, dass dies Ihnen eine Vorstellung davon vermittelt, wie Sie eine lange Methode anwenden und sie in zweckorientiertere Klassen unterteilen können. Sicher, mehrere Klassen zu haben, mag sich auf den ersten Blick komisch anfühlen, aber das bedeutet nicht, dass es eine schlechte Sache ist. Habe mehr Dateien (und damit Klassen) mit weniger Code als eine Datei mit viel Code ist besser.
Umfassen Sie in dieser Hinsicht den nicht eingängigen Charakter der objektorientierten Programmierung. Im nächsten Tutorial kehren wir zu unserem Plugin zurück und arbeiten an der Implementierung einer Variation des obigen Codes. Wir werden wahrscheinlich auch etwas davon debuggen. Denn wir machen es beim ersten Mal selten richtig
Wenn Sie bis dahin mehr über die objektorientierte Programmierung in WordPress erfahren möchten, finden Sie alle meine vorherigen Tutorials auf meiner Profilseite. Fühlen Sie sich frei, meinem Blog zu folgen oder folgen Sie mir auf Twitter, wo ich häufig über beides spreche.
Ressourcen