模块化设计模式

时间:2012-01-13 21:05:06

标签: php oop design-patterns modularity aop

我正在尝试决定系统的设计,以便实现大量的可扩展性。据我所知,除了重复代码(如下所示)之外,抽象工厂等模式不允许覆盖基本方法。

我已经对面向方面的编程做了一些初步的研究,它似乎与我正在寻找的东西一致,但是我很难围绕这些具体细节。

abstract class Object {

    protected $object_id;
    protected $name;

    function LoadObjectData()
    {
        $file_contents = readfile('object'.$object_id.'.data');
        $data = array();
        // parse file contents into $data array...
        return $data;
    }

    function Create()
    {
        $data = $this->LoadObjectData();
        $name = $data['name'];
        return $data;
    }

}

class User extends Object {

    protected $email_address;

    function Create()
    {
        $data = parent::Create();
        $this->email_address = $data['email_address'];
        return $data;
    }

}

//----------Module 1-MySQL Lookup-------------
/*
 * Redefine Object::LoadObjectData() as follows:
*/

function LoadObjectData()
{
    $data = array();
    $result = mysql_query("SELECT...");
    // construct array from result set
    return $data;
}

//----------Module 2-Cache Machine-------------
/*
 * Redefine Object::LoadObjectData() as follows:
 */

function LoadObjectData()
{
    if (exists_in_cache($object_id)) {
        return get_cached_object($object_id);
    }
    $data = parent::LoadObjectData();
    cache_object($object_id, $data);
    return $data;
}

(这是一个很糟糕的例子,但希望它能帮我解决问题)

预期的系统将有很大比例的方法可供扩展,我希望尽量减少开发人员所需的额外工作和学习。

AOP究竟是我正在寻找的,还是有更好的方法来解决这个问题?

谢谢!

2 个答案:

答案 0 :(得分:0)

因此,您希望使用装饰器模式而不定义装饰器本身。

如果是,那么这是一个monkeypatching,可以使用面向方面的工具完成。这可以通过以下扩展和框架轻松解决:

  1. PHP Runkit Extension
  2. Go! Aspect-Oriented framework for PHP
  3. PHP-AOP Extension

答案 1 :(得分:-1)

您不必将基类声明为抽象类。您可以使它成为常规类,并根据传递的构造参数加载并实例化其他类。构造函数可以返回类的实例,而不仅仅是构造函数所在的类。为了避免重复代码,可以将static与实例化的函数和变量混合使用。请记住,静态函数或变量对于所有实例都是相同的。在一个中更改静态变量,并为所有实例更改它。插件架构的一个相当基本的例子。

class BaseObject {
    protected static $cache = array();

    public function __construct($load_plugin) {
        require_once($load_plugin.'.class.php');
        $object  = new $load_plugin();
        return $object;
    }

    public static function cacheData($cache_key, $data) {
        self::$cache[$cache_key] = $data;
    }
}

class Plugin extends BaseObject {
    public function __construct() {
    }

    public function loadData() {
        // Check the cache first
        if ( !isset(self::$cache[$cache_key]) ) {
            // Load the data into cache
            $data = 'data to cache';
            self::cacheData($cache_key, $data);
        }
        return self::$cache[$cache_key];
     }
}