模块化设计模式

发布于 2024-12-27 02:11:17 字数 1493 浏览 5 评论 0原文

我正在尝试决定一个旨在允许高度可扩展性的系统的设计。据我所知,除了重复代码之外,诸如抽象工厂之类的模式不允许重写基本方法(如下所示)。

我已经对面向方面的编程进行了一些初步研究,它似乎符合我正在寻找的内容,但我很难理解具体细节。

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 正是我正在寻找的,还是有更好的方法来处理这个问题?

谢谢!

I'm trying to decide the design of a system which is meant to allow for a high amount of extensiblity. From what I can tell, a pattern such as the abstract factory would not allow for overriding of the base methods, apart from duplicating code (as demonstrated below).

I've done some preliminary research into aspect oriented programming and it seems to be along the lines of what I'm looking for but I'm having a difficult time wrapping my head around the specifics.

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

(This is sort of a poor example, but hopefully it helps to get my point across)

The intended system would have a very large proportion of methods available to be extended and I would like to minimize the extra effort and learning necessary for developers.

Is AOP exactly what I'm looking for, or is there a better way to deal with this?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

纸伞微斜 2025-01-03 02:11:17

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

如果是,那么它就是一个猴子补丁,可以使用面向方面的工具来完成。使用以下扩展和框架可以轻松解决此问题:

  1. PHP Runkit 扩展
  2. 走吧! PHP 面向方面的框架
  3. PHP-AOP 扩展

So, you want to use a decorator pattern without defining the decorator itself.

If yes, then it's a monkeypatching and can be done with aspect-oriented tools. This can be solved easily with following extensions and frameworks:

  1. PHP Runkit Extension
  2. Go! Aspect-Oriented framework for PHP
  3. PHP-AOP Extension.
死开点丶别碍眼 2025-01-03 02:11:17

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

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

You don't have to declare the base class as an abstract class. You can make it a regular class and have it load and instantiate other classes based on passed construct parameters. The constructor can return an instance of a class, not just the class the constructor is in. To avoid duplicating code, you can mix static with instantiated functions and variables. Just remember that a static function or variable is the same for ALL instances. Change a static variable in one and it is changed for all instances. A rather basic example of a plugin architecture.

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];
     }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文