在没有多重继承的情况下,在这个PHP类结构中使用什么是合适的设计模式


What would be the appropriate design pattern to use in this PHP class structure, given no multiple-inheritance?

我有一个名为Node的抽象类。它包含一个构造函数,它从我的数据库中获取一行,并实例化基本信息。我网站上的所有内容都扩展了这个类——PersonEventProject等。

其中3个扩展类是特殊的——在构建它们时,除了从数据库中提取值外,它们还需要查询web服务;如果web服务提供的值与数据库中给定的值不同,则需要将其保存到数据库中。

在具有多重继承能力的语言中,这将相当简单;这些类中的任何一个都将扩展NodeAPIData,或者类似的东西。没有MI,我不知道该如何处理。使用接口是没有帮助的,因为它没有提供具体的实现。

装饰器模式有时被推荐作为MI某些功能的替代,但我没有足够的经验来确定这是否是合适的选择。有什么建议吗?

对象应该是哑的。当我构建某个东西时,它不应该做我要求它做的事情之外的任何事情——也就是构建你自己。不要查询Web服务并写入数据库。如果我在你的团队中使用你的对象作为另一个开发人员,我会感到震惊。

这也是为什么我认为您正在努力寻找正确的模式,因为您的对象有多个关注点。

我认为这里最好的方法是创建一个返回对象的服务,例如PersonService、EventService等,它可以执行以下操作:

  • 从数据库检索记录
  • 如果需要查看Web服务:
    • 从Web服务检索数据
    • 如果存在更改,请保存回数据库
  • 将记录传递给对象构造器
  • 返回对象

这将Web服务调用的关注点放在一个有意义的地方——也就是说,检索必要数据以构建和返回对象的代码,也就是服务(EDIT:实际上更像是一个DAO,但你已经明白了)。

由于APIData类将从Node类中获得函数性,因此您应该简单地扩展它

abstract class APIData extends Node {
    public function __construct($data) {
        parent::__construct($data);
        $this->checkData();
    }
    protected function checkData() {
        // load data from webservice
        $data = $this->loadData();
        // check if data is the same
        foreach($data as $item => $value) {
            if ($this->data[$item] != $value) {
                // save in database
            }
        }
    }
}

你不应该像"好吧,我要实现一个装饰器模式"那样坐下来选择一个设计模式。相反,你应该按照它应该工作的方式设计代码,设计模式会因此而发展。碰巧我们有很多现有的术语来描述一些常见的设计模式,知道它们的名称可以让描述它们变得更容易。

不管怎样,我还是建议你往上走,不要往下走。您可以有一个由NodeAPIData对象组成的单独对象,并通过它们进行单独的工作,而不是扩展Node并试图以某种方式强制APIData

当PHP 5.4推出它的特性时,这将变得容易得多。