什么是确保从广义搜索查询中正确子类的策略


What is a strategy to ensure proper subclasses from a generalized search query?

这是一个通用的场景。我有"任务",我有"任务事件"。我已经为每个数据库创建了一个数据库表。我还创建了一个处理从数据库中获取记录的模型。

对于"任务事件",我有几种类型:已创建、已接受、评论、已关闭。

目前,我做一些简单的事情,比如$task = new Task($task_id);从数据库中获取任务,$task_events = new Tasks_Events($task_id);抓取该任务的事件。然后,我已经实现了迭代器,所以我可以做foreach($task_events as $e) { ... }这一切都很好用。

但是,我发现我需要一些专门的处理程序来处理一些事件类型。例如,我创建了扩展Tasks_Events的Tasks_Events_Comments,并对 Comment 事件类型进行了一些额外的处理。我现在意识到的是,当我收集事件集合时,我确实需要它们是子类型,因此,如果对事件调用方法,则会调用子类型的正确重写。

下面是一个快速示例:

class Model {
    public function __construct($search = null) {
        // Hypothetical example, basically query the DB and populate data.
        if (!is_null($search)) { $this->search($search); }
    }
    protected function onAfterUpdate() { }
}
class Tasks_Events extends Model {
    protected function onAfterUpdate() { /* Task Event Specific */ }
}
class Tasks_Events_Comments extends Tasks_Events {
    protected function onAfterUpdate() { /* Task Event Comment Specific */ }
}

然后,一个假设的用例:

class Controller {
    public function updateEvent($task_id, $event_id, $params) {
        $task = new Tasks($task_id);
        $task_event = new Tasks_Events($event_id);
        // Some Analysis of Params
        $task_event->status = $new_status;
        $task_event->save();
    }
}

所以,这是关键。这样做会调用Tasks_Events onAfterUpdate((...

我的问题是,我可以使用的模型、范式、哲学和方法是什么,这样当我有一个任务事件的集合,并且我对一个事件采取行动时,即使我使用的是基类引用,我也需要调用子类函数。

我真的很喜欢$e = new Tasks_Events(3); $e->status = 4; $e->save();我不喜欢的一个解决方案的简单性,就是做一些类似$e = Tasks_Events::Get($id);的事情,Tasks_Events查询数据库,确定类型,然后做一个"开关"并创建要返回的正确类型。

我不喜欢这样做的另一个原因是因为我已经建立了模型来做像$tasks = new Tasks(array('user_id' => 5, 'status' => Tasks::STATUS_OPEN));这样很酷的事情,它将构建正确的数据库查询,并填充用户 5 的所有打开的任务。然后我可以做foreach($tasks as $t) { echo $t->subject; }等等。所以,我希望能够保留这种系统......但我不确定如果我想利用子类型的继承,我是否可以

恐怕我可能需要工厂模式,但我希望我可能只是错过了一些东西。

附言如果您能想到更好的标题,请随时更改它。

感谢@Sam Dufel,您的评论让我思考得更深入,我意识到我的设计存在一个重大缺陷。

你对$task->getEvents((提出了一个很好的建议,但我忘记了我的问题中的一个关键(缺陷?(。这可能也是我遇到麻烦的原因...

基本上,我实现迭代器的方式,getter/setters可能是问题的根源。因为它迭代原始记录数组。

然后,假设我在迭代器中的位置为 2。调用$item->状态,调用检查$this->records[$this->position][$name]的__get($name(!!所以,正如你所看到的,我把自己画在一个角落里。即使使用工厂模式,由于我在Tasks_Events内部实现迭代器的方式,这也不能完全工作(嗯......模型(啊。

很抱歉打扰你们。谢谢你的想法。

更新:我意识到我所做的是将"DAO"与"模型"相结合,并有效地将"模型集合"结合起来。我要把它们分开。DAO->find(( 将返回一个模型集合(这将是可迭代的(,DAO->findOne(( 将返回一个模型。将这三者合二为一很方便,但随着我需求的扩展,它的可扩展性不是很高。