WordPress-Plugin: Wie vermeide ich „Tight Coupling“?

Lesezeit: 6 Minuten

WordPress Plugin Wie vermeide ich „Tight Coupling
Jeremy Harris

Ich arbeite an einem WordPress-Plugin und versuche, Best Practices sicherzustellen. Ich habe zwei Klassen, meine Plugin-Klasse “Jargonaut”, die erforderlich ist, und dann eine weitere Klasse namens “Dictionary”, die enthalten ist require_once() in meine Haupt-Plugin-Datei.

Der größte Teil des Codes in der Jargonaut-Klasse befasst sich mit der Initialisierung und bietet Controller-ähnliche Funktionalität, aber ein Großteil davon hängt stark von der Verwendung des Dictionary-Objekts ab (dh eng mit meinem Verständnis des Begriffs verbunden). Ich möchte die Dictionary-Klasse getrennt halten, da sie sich eher wie ein Modell (in der MVC-Architektur) verhält und mit meiner Datenbank verbunden ist.

Ich sehe viele Grauzonen in der engen vs. losen Kopplung und es fällt mir schwer zu entscheiden, wie viel zu viel ist?

  • Kannst du die Frage präzisieren? Wenn Sie eine Aussage mit einem Fragezeichen beenden, wird sie nicht zu einer Frage?

    – mdahlman

    31. Dezember 2011 um 14:53 Uhr

  • Dies sollte wahrscheinlich zu WPSE migriert werden.

    – Ian Dunn

    17. Februar 2012 um 1:18 Uhr

1646181548 952 WordPress Plugin Wie vermeide ich „Tight Coupling
hakre

Wenn Ihr Plugin das Dictionary-Objekt benötigt, muss es danach fragen:

class MyPlugin
{
    /**
     * @var Dictionary
     */
    private $dictionary;
    private function __construct(Dictionary $dictionary)
    {
        $this->dictionary = $dictionary;
    }

Sie haben nun Ihr Plugin lose mit der gekoppelt Dictionary, ist die Plugin-Klasse nicht mehr dafür verantwortlich, das Wörterbuch für sich selbst zu erstellen, da es injiziert wird. Es nimmt, was es braucht.

Wie würde das funktionieren? Das Plugin muss irgendwo erstellt werden, also braucht es eine Factory. Die Factory-Build-Methode weiß, was Ihr Plugin benötigt:

class MyPluginFactory
{
    public static function build($pluginName)
    {
        $plugin = NULL;
        switch($pluginName)
        {
            case 'MyPlugin':
                $dictionary = new Dictionary();
                $plugin = new MyPlugin($dictionary);
        }
        return $plugin;
    }
}

Da dies WordPress ist, wissen wir, dass das Bootstrapping des Plugins durch Einbinden der Plugin-Datei erfolgt. Am Anfang muss also das Plugin erstellt werden. Da Includes im globalen Bereich durchgeführt werden, möchten wir das Plugin-Objekt im Speicher erhalten, aber wahrscheinlich ohne als globale Variable verfügbar zu sein. Dies hindert Sie nicht daran, mehr als eine Plugin-Instanz zu erstellen, stellt jedoch sicher, dass WordPress beim Initialisieren Ihres Plugins (Laden Ihres Plugins) nur diese einzelne Instanz verwendet. Dies kann erreicht werden, indem die Plugin-Factory mit einer zusätzlichen Funktion versehen wird:

class MyPluginFactory
{
    ...
    public static $plugins;
    public static function bootstrap($pluginName)
    {
        $plugin  = self::build($pluginName);
        self::$plugins[] = $plugin;
        return $plugin;
    }

Achten Sie hier darauf, dass die einzige Verwendung der statischen Klassenmember-Variablen nur darin besteht, sicherzustellen, dass das Plugin im Speicher bleibt. Technisch gesehen ist es eine globale Variable, die wir normalerweise verhindern möchten, aber die Instanz muss irgendwo gespeichert werden, also hier ist sie (ich habe dies in öffentlich geändert, weil es ist eine globale Variable und sollte nicht davor zurückschrecken. Eine Öffentlichkeit zu haben kann unter Umständen hilfreich sein, in denen privat oder geschützt zu restriktiv sind. Auch sollte es kein Problem sein. Wenn es ist ein Problem, gibt es ein anderes Problem, das zuerst behoben werden sollte).

Dies entkoppelt im Grunde Ihren Plugin-Code von WordPress selbst. Vielleicht möchten Sie auch eine Klasse erstellen, die eine Schnittstelle zu jeder WordPress-Funktion bietet, die Sie verwenden, sodass Sie nicht direkt an diese Funktionen gebunden sind und Ihr Plugin-Code sauber und lose mit WordPress selbst gekoppelt bleibt.

class WordPressSystem
{
    public function registerFilter($name, $plugin, $methodName)
    {
        ... do what this needs with WP, e.g. call the global wordpress function to register a filter.
    }
    ...
}

Fügen Sie es dann erneut als Abhängigkeit hinzu, wenn Ihr Plugin die benötigt WordPressSystem um Aufgaben auszuführen (was normalerweise der Fall ist):

class MyPlugin
{
    ...
    public function __construct(WordPressSystem $wp, Dictionary $dictionary)
    ...

Um dies endlich abzuschließen, wird nur die Plugin-PHP-Datei benötigt:

<?php
/*
 * MyPlugin
 * 
 * Copyright 2010 by hakre <hakre.wordpress.com>, some rights reserved.
 *
 * WordPress Plugin Header:
 * 
 *   Plugin Name:    My Plugin
 *   Plugin URI:     http://hakre.wordpress.com/plugins/my-plugin/
 *   Description:    Yet another wordpress plugin, but this time mine
 *   Version:        1.2-beta-2
 *   Stable tag:     1.1
 *   Min WP Version: 2.9
 *   Author:         hakre
 *   Author URI:     http://hakre.wordpress.com/
 *   Donate link:    http://www.prisonradio.org/donate.htm
 *   Tags:           my
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
Namespace MyPlugin;

# if your file is named 'MyPlugin.php' this will be 'MyPlugin'.
return PluginFactory::bootstrap(basename($plugin, '.php'));

class PluginFactory
{
    private static $plugins;
    public static function bootstrap($pluginName)
    {
        $plugin = self::build($pluginName);
        self::$plugins[] = $plugin;
        return $plugin;
    }
    public static function build($pluginName)
    {
        $plugin = NULL;
        switch($pluginName)
        {
            case 'MyPlugin':
                # Make your plugin work with different WordPress Implementations.
                $system = new System\Wordpress3();
                $dictionary = new Dictionary();
                $plugin = new Plugin($system, $dictionary);
        }
        return $plugin;
    }
}

class Plugin
{
    /**
     * @var System
     */
    private $system;
    /**
     * @var Dictionary
     */
    private $dictionary;
    private function __construct(System $system, Dictionary $dictionary)
    {
        $this->system = $system;
        $this->dictionary = $dictionary;
    }

...

Die Bootstrap-Methode kann sich auch um die Registrierung eines Autoloaders kümmern oder die Anforderungen erfüllen.

Hoffe, das ist nützlich.

  • @hakre – Der Versuch, deinem Beispiel zu folgen, sieht so aus $this->build($pluginName) gewesen sein sollte self::build($pluginName) da es sich um eine statische Funktion handelt, oder? (Ich habe eine entsprechende Änderung vorgenommen, die zuerst überprüft werden muss.) Aber ich bin verwirrt von Ihrer return-Anweisung, die zurückkehrt MyPluginFactory::bootstrap(); Ich sehe nicht, was Sie aufrufen möchten, und ich wusste nicht, dass Sie eine .PHP-Datei als Funktion aufrufen können. wie ist das möglich? Oder hast du nur Pseudocode angezeigt?

    – MikeSchinkel

    1. Januar 2012 um 0:36 Uhr

  • @hakre – Mehr recherchieren (Ich habe noch nicht begonnen, Namespaces zu verwenden)es sieht aus wie Ihr Anruf an MyPluginFactory::bootstrap() sollte wirklich sein \MyPlugin\Factory::bootstrap(), rechts? Ich bin mir immer noch nicht sicher, wie die Rückgabe eines Werts aus einer .PHP-Datei funktioniert …

    – MikeSchinkel

    1. Januar 2012 um 0:59 Uhr


  • Dies ist Beispielcode, er ist syntaktisch nicht gültig, sondern zeigt nur etwas. Siehe auch das “…” am Ende, das eine ordnungsgemäße Ausführung verhindert. Ich bin mir auch nicht sicher, ob die Verwendung der use-Klausel zum Ändern des WordPressSystems nicht falsch ist, da sich die Fabrik darum kümmern sollte. Ich werde das zusammen mit den von Ihnen erwähnten Punkten beheben.

    – hakre

    1. Januar 2012 um 1:21 Uhr

  • Ich denke auch, dass Sie verwendet haben sollten public function __construct(Dictionary $dictionary) anstatt private function __construct(Dictionary $dictionary) in dem MyPlugin Klasse, weil Sie haben new MyPlugin($dictionary);.

    – Das Alpha

    30. August 2013 um 23:00 Uhr

  • Ich weiß, dass das SEHR alt ist, aber ich versuche, einiges davon in meinen Kopf zu bekommen … In diesem Beispiel PluginFactory soll eine Fabrik sein, um viele verschiedene Plugins zu instanziieren, richtig? Und $plugin soll vor dem Aufruf initialisiert werden bootstrap?

    – Yiv

    3. August 2016 um 15:10 Uhr

906530cookie-checkWordPress-Plugin: Wie vermeide ich „Tight Coupling“?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy