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

时间:2012-05-13 23:19:40

标签: php mysql oop design-patterns

这是一个广义的场景。我有"任务"我有"任务事件。"我为每个人创建了一个数据库表。我还创建了一个处理从数据库中提取记录的模型。

对于"任务事件,"我有几种类型:Created,Accepted,Comment,Closed。

目前,我做了一些像$task = new Task($task_id);这样简单的事情来从数据库中获取任务,而$task_events = new Tasks_Events($task_id);则抓取了该任务的事件。然后,我已经实现了Iterator,所以我可以做foreach($task_events as $e) { ... }这一切都很有效。

但是,我发现我需要一些专门的处理程序来处理一些事件类型。例如,我创建了Tasks_Events_Comments,它扩展了Tasks_Events,并为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();
    }
}

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

我的问题是,我可以使用的模型,范例,哲学和方法是什么,以便当我有一系列任务事件时,我会对其进行操作,即使我&#39 ; m使用基类引用,我需要调用子类函数。

我真的很喜欢$e = new Tasks_Events(3); $e->status = 4; $e->save();我所拥有的一个解决方案的简单性,我不喜欢做$e = Tasks_Events::Get($id);之类的事情,其中​​Tasks_Events将查询数据库,确定类型,然后执行a"开关"并创建要返回的正确类型。

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

我担心我可能需要工厂模式,但我希望我可能会遗漏某些东西。

P.S。如果你能想到一个更好的头衔,请随时改变它。

1 个答案:

答案 0 :(得分:0)

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

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

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

然后,假设我在迭代器中的位置2。调用$ item->状态,调用__get($ name)来检查$this->records[$this->position][$name] !!所以,正如你所看到的,我把自己画成了一个角落。即使使用工厂模式,由于我在Tasks_Events(以及......模型)中实现迭代器的方式,这也不会有效。

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

更新:我意识到我所做的是将“DAO”与“模型”与“模型集合”结合起来。我要分开他们。 DAO-> find()将返回一个Model Collection(可以迭代),以及DAO-> findOne()将返回一个Model。将三者合二为一会很方便,但随着我的需求的扩大,它不是很容易扩展。