WordPress插件:如何避免“紧密耦合"? [英] WordPress Plugin: How do I avoid "tight coupling"?

查看:76
本文介绍了WordPress插件:如何避免“紧密耦合"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究WordPress插件,并试图确保最佳实践.我有两个类,我的插件类"Jargonaut"是必需的,然后是另一个类"Dictionary",该类随require_once()一起包含在我的主插件文件中.

I am working on a WordPress Plugin and am trying to ensure best practices. I have two classes, my plugin class "Jargonaut" which is required and then another class called "Dictionary" which is included with require_once() into my main plugin file.

Jargonaut类中的大多数代码都处理初始化问题,并提供类似控制器的功能,但是其中很大一部分高度依赖于使用Dictionary对象(即,根据我对该术语的理解紧密结合).我希望让Dictionary类保持分离,因为它的行为更像是一个模型(在MVC体系结构中)并与我的数据库进行交互.

Most of the code in the Jargonaut class addresses initialization and provides controller-like functionality but much of it is highly dependent upon using the Dictionary object (i.e. tightly coupled from my understanding of the term). I wish to keep the Dictionary class separated as it is acting more like a model (in MVC architecture) and interfaces with my database.

在紧密耦合与松散耦合中,我看到了很多灰色区域,并且很难确定多少太大了?

I see a lot of gray area in the tight vs. loose coupling and am having a hard time deciding how much is too much?

推荐答案

如果您的插件需要字典对象,则必须要求它:

If your plugin needs the dictionary object, it has to ask for it:

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

您现在已将插件与Dictionary松散耦合,插件类不再负责为其自身创建Dictionary,因为它已被注入.它需要它.

You now have loosely coupled your plugin with the Dictionary, the plugin class is not responsible any longer to create the Dictionary for itself, because it's injected. It takes what it needs.

那怎么办?该插件需要在某个地方创建,因此需要工厂.工厂构建方法知道您的插件需要什么:

So how would that work? The plugin needs to be created somewhere, so this needs a factory. The factory build method knows what your plugin needs:

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

由于这是wordpress,我们知道插件的自举是通过包含插件文件来完成的.因此,在开始时,需要创建插件.就像在全局范围内所做的那样,我们希望将插件对象保留在内存中,但可能无法用作全局变量.这不会阻止您创建多个插件实例,但是会确保在wordpress初始化插件(加载插件)时,它将仅使用该单个实例.这可以通过使插件工厂具有一些附加功能来完成:

As this is wordpress we know that the bootstrapping of the plugin is done by including the plugin file. So at it's beginning, the plugin needs to be created. As includes are done in the global scope we want to preserve the plugin object in memory but without being available as a global variable probably. This does not prevent you from creating more than one plugin instance, but it will ensure that when wordpress initializes your plugin (loads your plugin), it will make only use of that single instance. This can be done by making the plugin factory some additional function:

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

请注意,静态类成员变量的唯一用法仅是确保插件保留在内存中.从技术上讲,它是我们通常要防止的全局变量,但是,实例需要存储在某个位置,因此在这里(我将其更改为公共变量,因为它,并且不应害羞.在私人或受保护的限制过于严格的某些情况下,公众可以提供帮助.这也不应该成为问题.如果这是一个问题,那么还应该解决另一个问题首先确定.)

Take care here, that the only usage of the static class member variable is only to ensure that the plugin stays in memory. It technically is a global variable we normally want to prevent, however, the instance needs to be stored somewhere, so here it is (I changed this to public because it is a global variable and it shouldn't be shy about it. Having a public can help in some circumstances in which private or protected are too restrictive. Also it shouldn't be a problem. If it is a problem, there is another problem that should be fixed first).

这基本上使您的插件代码与wordpress本身脱钩.您可能还想创建一个类,该类为您正在使用的任何wordpress函数提供并提供接口,因此您不必直接绑定到这些函数,并且插件代码可以保持整洁并松散地耦合到wordpress本身.

This basically decouples your plugin code from wordpress itself. You might want to also create a class that offers and interface to any wordpress function you're making use of, so you're not bound to these functions directly and your plugin code stays clean and loosely coupled to wordpress itself.

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.
    }
    ...
}

然后,如果您的插件需要WordpressSystem来执行任务(通常是这种情况),则再次将其添加为依赖项:

Then add it as a dependency again if your plugin needs the WordpressSystem to perform tasks (which normally is the case):

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

因此,要最终完成这一过程,只需要插件php文件:

So to finally wrap this up, only the plugin php file is needed:

<?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;
    }

...

bootstrap方法还可以用于注册自动装带器或执行要求.

The bootstrap method can also take care of registering an autoloader or do the requires.

希望这很有用.

这篇关于WordPress插件:如何避免“紧密耦合"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆