Teil 2 – WordPress und objektorientierte Programmierung: Ein Beispiel aus der Praxis

Veröffentlicht: 2021-07-29

In unserem Überblick über WordPress und objektorientierte Programmierung haben wir die Theorie hinter der objektorientierten Programmierung (OOP) durchgegangen und was Sie bei der Verwendung erwarten können.

Bevor wir mit spezifischeren Codierungsbeispielen mit OOP fortfahren, versuchen wir in diesem Artikel zu erklären, wie ein reales Szenario mit der für OOP erforderlichen unterschiedlichen Denkweise angegangen werden kann und wie dies mithilfe von Objekten und Klassen analysiert wird.

Ein reales Szenario: Eine SMS versenden

Dies ist eher ein Szenario aus dem „früheren“ Leben, da SMS heutzutage immer weniger verwendet werden, aber wie Sie sehen werden, gibt es einen Grund, warum wir dies als Beispiel verwenden!

Angenommen, Sie haben ein mobiles Gerät und möchten eine Textnachricht an einen Ihrer Kontakte senden. Um das Beispiel so einfach wie möglich zu halten, wäre die Reihenfolge der Aktionen:

  1. Bereiten Sie die Nachricht vor
  2. Wählen Sie einen Ihrer Kontakte aus und fügen Sie ihn als Empfänger hinzu
  3. Senden Sie die Nachricht

Lassen Sie uns also versuchen, die Schritte zu visualisieren, die Sie befolgen würden, um Ihre Nachricht zu senden:

Wir haben einige detailliertere Beschreibungen der Aktionen hinzugefügt, aber mehr oder weniger alles, was Sie tun müssen, sind 3 grundlegende Schritte. Sie bereiten die Nachricht im Geräte-Editor vor, wählen den Empfänger aus Ihren Kontakten aus und versenden die Nachricht. Und du bist fertig! Ihre Nachricht wird jetzt gesendet.

Wenn wir nun im Code eine Anwendung darstellen, die eine SMS-Nachricht sendet, sollten wir analysieren, welcher Route besser zu folgen ist; der prozedurale oder OOP-Ansatz.

Die Anwendung mit einem Verfahrensansatz

Wenn Sie ein WordPress-Plugin-Entwickler sind, sind Sie höchstwahrscheinlich mit prozeduraler Programmierung vertraut.

Wie wir bereits beschrieben haben, ist die prozedurale Programmierung eine Art imperativer Programmierung, bei der unsere Programme aus einer oder mehreren Prozeduren bestehen. Als Entwickler unterteilen Sie also Ihr Plugin in eine Reihe von Variablen , die Ihre Daten enthalten, und Funktionen , die mit den Daten arbeiten.

In unserem obigen Beispiel mit der SMS-Nachricht würden Sie eine Reihe von Aktionen ausführen, die zum gewünschten Ergebnis führen würden. Wie Sie vielleicht schon erraten haben, hätten Sie beispielsweise eine Variable, die den Textinhalt der Nachricht enthält, eine Funktion mit einem $contact Parameter, die die Telefonnummer zurückgibt, und schließlich eine Funktion, die die Nachricht sendet. Im Code würde es so aussehen:

 function get_phone_number( $contact ) { // Code that finds the contact's number in the list of contacts return $phone_number; } function send_sms( $contact, $message ) { $phone_number = get_phone_number( $contact ); // Code that sends the message to this number print "Message Sent!"; }

Und Sie würden es so verwenden:

 $text = "Hello John"; function send_message( "John Doe", $text );

Sie würden also eine Reihe von Aufgaben erledigen, die Sie zum gewünschten Ergebnis führen.

In diesem sehr einfachen Beispiel mit begrenzten und sehr spezifischen Anforderungen gibt es natürlich keinen Grund, OOP überhaupt zu verwenden. Prozedurale Programmierung ist mehr als genug, um Ihr Ziel zu erreichen. Aber wenn Sie an einige Szenarien denken, wie diese Anwendung in Zukunft expandieren könnte, stellen Sie vielleicht fest, dass Sie auf lange Sicht Probleme in Bezug auf die Skalierbarkeit haben könnten. Wir werden versuchen, warum unten zu erklären.

Erweiterung der Anwendung mit prozeduralem Ansatz

Angenommen, Sie möchten diese Anwendung verbessern und die Möglichkeit bieten, auch andere Arten von Nachrichten zu senden, z. B. eine E-Mail. Die Funktion, die die Nachricht liefert, wäre in jedem Fall unterschiedlich.

Beim Senden einer E-Mail benötigen Sie die E-Mail-Adresse des Kontakts, nicht die Telefonnummer. Abgesehen davon müssen wir in der letzten Funktion send_message() einen Parameter hinzufügen, der der Art der von uns verwendeten Technologie entspricht; E-Mail oder SMS.

Der entsprechende Code könnte etwa so aussehen:

 function get_phone_number( $contact ) { // Code that finds the contact's number return $phone_number; } function get_email_address( $contact ) { // Code that finds the contact's email address return $email_address; } function send_sms( $contact, $message ) { $phone_number = get_phone_number( $contact ); // Code that sends the message to this number print "SMS Sent!"; } function send_email( $contact, $message ) { $email_address = get_email_address( $contact ); // Code that sends the email to this number print "Email Sent!"; } function send_message( $contact, $message, $technology ) { if ( $technology == "SMS") { send_sms( $phone_number, $message ); } else if ( $technology == "Email") { send_email( $email_address, $message ); } }

Es ist also nicht so, dass dies nicht mit einem prozeduralen Ansatz umgesetzt werden könnte. Aber wenn Sie ein erfahrener Entwickler sind, haben Sie wahrscheinlich bereits verstanden, wie dies in Zukunft chaotisch werden könnte.

Die Nachteile eines prozeduralen Ansatzes

Was wäre, wenn wir mehrere Arten von Nachrichten hätten? Die if -Anweisungen würden lästig groß werden. Und vor allem, was wäre, wenn Sie Funktionen hätten, die die Funktion send_message() verwenden? In diesem Fall müssten Sie in all diesen Funktionen auch den Parameter $technology hinzufügen.

Wenn Ihr Code wächst, werden Funktionen überall sein, was bedeutet, dass Sie anfangen werden, Code-Blöcke zu kopieren/einzufügen (nie wünschenswert), und eine kleine Änderung an einer Funktion kann mehrere andere Funktionen beschädigen. Das haben wir alle schon durchgemacht. Sie möchten dies vermeiden und in der Lage sein, Ihrem Code Funktionen hinzuzufügen, ohne zu sehr in die Struktur einzugreifen.

Hosten Sie Ihre Website mit Pressidium

60- TÄGIGE GELD-ZURÜCK-GARANTIE

SEHEN SIE UNSERE PLÄNE

Objektorientierte Programmierung (oder OOP) ist ein Programmierparadigma, das versucht, dieses Problem zu lösen, indem es uns erlaubt, unser Plugin in kleine, wiederverwendbare Codeteile, Klassen genannt, zu strukturieren. Wie wir in unserem OOP-Übersichtsartikel beschrieben haben, ist eine Klasse im Grunde eine Vorlage, die wir verwenden, um einzelne Instanzen der Klasse zu erstellen, die als Objekte bezeichnet werden.

Ein Objekt enthält Daten und Code. Wir haben immer noch Variablen, die Informationen speichern können, die als Eigenschaften bezeichnet werden. Und Prozeduren, die mit den Daten arbeiten, sogenannte Methoden .

Die Anwendung mit einem OOP-Ansatz

Lassen Sie uns nun dasselbe Szenario wie oben mit einem OOP-Ansatz analysieren.

Zuerst werden wir definieren, welche Objekte wir hier haben, welche Eigenschaften sie haben und welche Aktionen sie ausführen. Die Merkmale sind unsere späteren Eigenschaften und Aktionen unsere Funktionen oder Methoden, wie sie in OOP genannt werden.

Denken wir darüber nach, was wir im ersten Szenario haben, eine SMS auf einfachste Weise zu versenden. Es gibt ein Gerät mit einer Schnittstelle, die wir zum Senden der SMS-Nachricht verwenden. Wir haben den Nachrichteninhalt, wir wählen einen Kontakt als Empfänger und schließlich die Nachricht.

 <?php /** * Plugin Name: Send Message */ interface MessagingCapable { public function send_message( $contact, $message ); } class Phone implements MessagingCapable { public function send_message( $contact, $message ) { print "You sent" . $message ; } } function say_hi( MessagingCapable $device, $contact, $message ) { $device->send_message( $contact, $message ); }

Wir deklarieren die Phone -Klasse, die die MessagingCapable -Schnittstelle implementiert. Wir müssen also alle darin deklarierten Methoden implementieren. Die Funktion say_hi() benötigt 3 Parameter:

  1. Ein Gerät, das Messaging unterstützt
  2. Ein Kontakt
  3. Die Nachricht

Um tatsächlich eine Nachricht zu senden, verwenden wir diese Funktion wie folgt:

 $phone = new Phone(); say_hi( $phone, "John Doe", "Hello John" );

Wir erstellen im Grunde ein Objekt, indem wir die Phone-Klasse instanziieren und den Kontakt- und Nachrichteninhalt übergeben. Dies würde ausgeben:

 You sent "Hello John"

Wir haben dieses einfache Szenario zum Senden einer Textnachricht mithilfe von Klassen demonstriert. Im nächsten Abschnitt werden wir sehen, wie wir die Fähigkeiten der Anwendung nach dem OOP-Ansatz erweitern können, und beim Hochskalieren werden wir untersuchen, wo die OOP-Funktionen ihre Rolle spielen, sowie die Vorteile der Verwendung dieser Technik.

Erweiterung der Anwendung mit dem OOP-Ansatz

Lassen Sie uns die Möglichkeit hinzufügen, auch E-Mails zu senden, wie wir es zuvor prozedural getan haben.

Unabhängig vom Gerät möchten wir die Funktion say_hi() idealerweise auf die gleiche Weise verwenden. Schauen Sie sich den folgenden Code an:

 <?php /** * Plugin Name: Send Message */ interface MessagingCapable { public function send_message( $contact, $message ); } class Phone implements MessagingCapable { public function send_message( $contact, $message ) { print ('You sent a "' . $message . '" SMS to ' . $contact ); } } class Computer implements MessagingCapable { public function send_message( $contact, $message ) { print ('You sent a "' . $message . '" email to ' . $contact ); } } function say_hi( MessagingCapable $device, $contact, $message ) { $device->send_message( $contact, $message ); }

Wenn wir diesen Code verwenden, würden wir das mobile Gerät in die Hand nehmen, um eine SMS zu senden, und den Computer, um eine E-Mail zu senden. Wir würden entweder:

 say_hi ( new Phone(), "John Doe", "Hello John" );

oder:

 say_hi ( new Computer(), "John Doe", "Hello John" );

das würde ausgeben You sent a "Hello John" SMS to John Doe You sent a "Hello John" email to John Doe entsprechend eine „Hello John“-E-Mail an John Doe gesendet.

Hier fangen wir bereits an, einige OOP-Features zu erkennen. Wir haben Schnittstellen mithilfe der MessagingCapable -Schnittstelle eingeführt.

Eine Schnittstelle deklariert eine Reihe von Methoden, die von der Klasse implementiert werden müssen, ohne zu definieren, wie diese Methoden implementiert werden. Alle in einer Schnittstelle deklarierten Methoden müssen öffentlich sein.

PHP unterstützt keine Mehrfachvererbung, was bedeutet, dass eine Klasse nicht die Eigenschaften/Methoden mehrerer übergeordneter Klassen erben kann.

Es kann zwar nur eine Klasse erweitern, aber mehrere Schnittstellen implementieren.

Die Verwendung eines Telefons zum Senden einer Nachricht unterscheidet sich von der Verwendung eines Computers. Instanzen verschiedener Klassen verhalten sich unterschiedlich, wenn sie aufgefordert werden, dieselbe Aktion auszuführen (dh send_message() ). Dies ist ein Beispiel für Polymorphismus. Wenn wir später ein neues Gerät erstellen, müssen wir unseren Code nicht ändern, um es aufzunehmen, solange sie alle dieselbe Schnittstelle teilen.

Wir möchten hier auch darauf hinweisen, dass wir den Unterschied auch schon in der Lesbarkeit sehen. Die Art und Weise, wie wir dieses Skript schließlich verwenden, indem wir einfach codieren:

 say_hi( new Computer(), "John", "Hi" );

Dies ist für jeden Entwickler, der an dem Projekt arbeitet, völlig unkompliziert. Und je komplexer das Plugin ist, desto deutlicher wird natürlich, wie hilfreich das gerade bei der Arbeit im Team ist.

Um zu versuchen und besser zu erklären, wie einfach es ist, Ihr Plugin in der objektorientierten Programmierung zu erweitern, versuchen wir, einige weitere Funktionen hinzuzufügen.

Hinzufügen weiterer Funktionen

Wenn wir die Möglichkeit zum Surfen im Internet hinzufügen möchten, würden wir einfach eine zusätzliche Schnittstelle für jedes Gerät hinzufügen, das auf diese Fähigkeit reagieren könnte, wie zum Beispiel einen Computer.

 interface InternetBrowsingCapable { public function visit_website( $url ); }

Die Implementierung dieser Schnittstelle wird wie folgt codiert:

 class Computer implements MessagingCapable, InternetBrowsingCapable { public function send_message( $contact, $message ) { print ('You sent a "' . $message . '" email to ' . $contact ); } public function visit_website( $url ) { print ('You visited "' . $url ); } }

Also haben wir in der aktuellen Computer-Klasse nur die zusätzliche zu implementierende Schnittstelle hinzugefügt, da ein Computer eine Nachricht senden und im Internet surfen kann, und die Methode visit_website( $url ) .

HINWEIS: Da der Besuch einer URL mit der Funktion say_hi() völlig irrelevant ist, werden wir natürlich auch eine neue Funktion einführen, etwa so:

 function visit_url( InternetBrowsingCapable $device, $url ) { $device->visit_website( $url ); }

Und das ist es! Für jedes Gerät, das eine URL besuchen kann, können wir diese Funktion wie beim Computer verwenden. Sie müssen sich keine Sorgen machen, dass Sie den Rest der Funktionalität beschädigen. Dies zeigt die verfügbare Skalierbarkeit bei der Verwendung von OOP im Vergleich zur prozeduralen Programmierung.

Lassen Sie uns ein Smartphone-Gerät hinzufügen, nur um einige weitere Funktionen zu demonstrieren. Hier ist der gesamte Code, mit dem Zusatz der Smartphone-Klasse, damit Sie sich ein besseres Bild davon machen können, was vor sich geht:

 <?php /* * Plugin Name: Communication Plugin */ interface MessagingCapable { public function send_message( $contact, $message ); } interface InternetBrowsingCapable { public function visit_website( $url ); } class Phone implements MessagingCapable { public function send_message( $contact, $message ) { print 'You sent a "' . $message . '" SMS to ' . $contact; } } class Computer implements MessagingCapable, InternetBrowsingCapable { public function send_message( $contact, $message ) { print 'You sent a "' . $message . '" email to ' . $contact; } public function visit_website( $url ) { print 'You visited "' . $url; } } class Smartphone extends Phone implements InternetBrowsingCapable { public function visit_website( $url ) { print 'You visited "' . $url; } public function send_message( $contact, $message ) { parent::send_message( $contact, $message ); print ' from your smartphone'; } } function say_hi( MessagingCapable $device, $contact, $message ) { $device->send_message( $contact, $message ); } function visit_url( InternetBrowsingCapable $device, $url ) { $device->visit_website( $url ); }

Die Smartphone-Klasse erweitert die übergeordnete Phone-Klasse und implementiert die InternetBrowsingCapable -Schnittstelle. Das heißt, es kann eine Nachricht senden und eine URL besuchen. Hier erkennen wir die Vererbungsfunktion. Mit anderen Worten, wir haben eine Klassenhierarchie, eine Elternklasse (Telefon) und eine Unterklasse (Smartphone).

Ein Smartphone-Objekt erbt also alle Eigenschaften und Verhaltensweisen der übergeordneten Phone-Klasse. Auf diese Weise können wir innerhalb der untergeordneten Klasse eine Methode hinzufügen oder eine Methode der übergeordneten Klasse überschreiben, wie wir es mit send_message() in der Smartphone-Klasse getan haben. Wir haben dies getan, um die Ausgabe zu ändern. Wir könnten diese Methode völlig ignorieren und send_message() der übergeordneten Klasse so verwenden, wie sie ist.

Sie können den Code selbst ausprobieren, indem Sie ihn in den Codeblock dieses großartigen PHP-Online-Tools einfügen. Probieren Sie unter dem Code eine dieser Codezeilen aus und sehen Sie sich die unterschiedlichen Ergebnisse an.

 say_hi ( new Phone(), "John Doe", "Hello John" ); say_hi ( new Computer(), "John Doe", "Hello John" ); say_hi ( new Smartphone(), "John Doe", "Hello John" ); visit_url ( new Smartphone(), "https://www.pressidium.com" ); visit_url ( new Computer(), "https://www.pressidium.com" );

Für ein noch besseres Verständnis des gesamten Konzepts werfen Sie einen Blick auf das Klassendiagramm des obigen Codes.

Wie oben dargestellt, schließen wir beim Entwerfen der Beziehungen zwischen Klassen die gemeinsamen Elemente nicht in die untergeordnete Klasse ein. Vergessen Sie außerdem nicht, auf den Leitfaden auf der linken Seite zu achten, damit Sie die Beziehungen und die Sichtbarkeit ihrer Eigenschaften und Methoden erkennen können.

Wenn Sie die Kapselungsfunktion auch in Aktion sehen möchten, versuchen Sie, eine Contact-Klasse in eines der oben bereitgestellten Beispielskripts einzufügen. Die Klasse würde so aussehen:

 class Contact { private $name; private $phone_number; private $email_address; public function __construct( $name, $phone_number, $email_address ) { $this->name = $name; $this->phone_number = $phone_number; $this->email_address = $email_address; } public function get_name() { return $this->name; } public function get_phone_number() { return $this->phone_number; } public function get_email_address() { return $this->email_address; } }

Die Methode __construct() wird standardmäßig automatisch bei der Erstellung eines Objekts aufgerufen. Wenn wir nun die Contact-Klasse instanziieren, wird ihr Konstruktor aufgerufen und legt die Werte ihrer privaten Eigenschaften fest. Dann verwenden wir unsere „Getter“, die die öffentlichen Methoden get_name() , get_phone_number() und get_email_address() sind, um diese Werte abzurufen.

Die Kapselung bündelt die Daten mit den Methoden, die mit den Daten arbeiten, während der direkte Zugriff eingeschränkt wird, wodurch verhindert wird, dass verborgene Implementierungsdetails offengelegt werden.

Fazit

Hoffentlich hat Ihnen dieser Artikel geholfen, die objektorientierte Programmierung auf praktischere Weise zu verstehen. OOP trägt wirklich dazu bei, dass die Anwendung in Zukunft bei Bedarf einfacher erweitert werden kann, da es übersichtlich und wiederverwendbar ist.

Darüber hinaus ist ein Plugin, das OOP verwendet, schneller und einfacher auszuführen. Das liegt daran, dass die Methoden, die allen Objekten einer Klasse gemeinsam sind, während ihrer Deklaration nur einmal Speicher verbrauchen.

Auch die Sicherheit wird durch die Kapselung verbessert. Bei der prozeduralen Programmierung hingegen sind alle Daten global, was bedeutet, dass der Zugriff von überall möglich ist.

Infolgedessen werden auch Codewartung, Produktivität, Skalierbarkeit und Fehlerbehebung für Sie und Ihr Team viel einfacher.

In den nächsten Artikeln dieser Serie werden wir diesen Programmierstil in Aktion sehen, indem wir ihn auf ein WordPress-Plugin anwenden. Insbesondere werden wir eine Kopie des Plugins Limit Login Attempts Version 1.7.1 erstellen, das von Johan Eenfeldt erstellt, aber so weit wie möglich mit einem objektorientierten Ansatz konvertiert wurde.

Während dieses Prozesses werden wir den Plugin-Fluss aufschlüsseln und die Anforderungen festlegen. In Zukunft werden wir unsere ersten Gedanken zum Design des Plugins ausprobieren und im Implementierungsschritt den Code schreiben. Während des Implementierungsprozesses werden wir einige Hin- und Herbewegungen machen und gegebenenfalls umgestalten, um die gewünschten Ergebnisse zu erzielen.

Wir werden jedoch nicht auf alle Teile des Codes eingehen. Stattdessen möchten wir uns darauf konzentrieren, wie Plugins objektorientiert erstellt werden. Wir sind zuversichtlich, dass Sie nach dem Lesen dieser Artikelserie sehr gut ein eigenes OOP-Plugin erstellen können.

Klicken Sie hier, um Teil 3 unserer Serie zur objektorientierten Programmierung zu lesen

Siehe auch

  • WordPress und objektorientierte Programmierung – Ein Überblick