2

我是 Doctrine 的忠实拥护者,但过去主要将其用于访问我的数据库的更简单和更 OO 的方式。尽管最近我发现自己想对模型做更多的事情,以使我的代码更具语义或逻辑性,并且易于使用。

例如,让我们使用堆栈溢出问题和相应的答案。一个问题可以包含一个或多个答案。在过去,我可能会做这样的事情(下面的所有内容都是 sudo 代码 btw):

/*
*   METHOD ONE: Note that this is IMO not that semantic or OO
*/
Class QuestionController{       

    //.......

    public function addAnswer($whichQuestionId, $answerTitle, $answerCopy, $answerAuthorId)
    {                       
        //Look, I'm validating stuff here in my controller action           
        if(!strlen($answerTitle) || !strlen($answerCopy) || !strlen($answerAuthorId))
            throw new \Exception('Invalid answer stuff!!');

        //Notice here I'm actually doing some DB quering with 
        $author = $entityManager->find('\StackOverflow\User', $answerAuthorId);
        if($author->getIsBanned())
            throw new \Exception('This is user can not post answer, they are banned!');         

        //OK, things are valid, now we're going to load then question and create a new answer           
        $question = $entityManager->find('\StackOverflow\Question', $whichQuestionId)       

        $answer = new \StackOverflow\Answer;
        $answer->setAuthor($author);
        $answer->setTitle($answerTitle);
        $answer->setContent($answerCopy);

        $question->addAnswer($answer);

        //Let's pretend we persisted everything correctly...
        //Done!

    }

    //.......       
}

Class \StackOverflow\Answer{
    //Normal auto generated stuff here
}

Class \StackOverflow\Qusetion{
    //Normal auto generated stuff here
}

好的,所以请注意,我在控制器操作中进行了所有验证,效果很好,但是如果我想在不同的控制器中添加一个问题的答案,那么这并不是很枯燥。我可以将此验证逻辑放在某种“助手”中,但这似乎也不是特别面向对象。

我宁愿做这样的事情(虽然不完全好,但希望你明白)

/*
 *  METHOD TWO: Hopefully a bit more OO...
 */ 

Class QuestionController{   

    public function addAnswer($whichQuestionId, $answerTitle, $answerCopy, $answerAuthorId)
    {
        $result = new \stdObject();

        try{

            $question = $entityManager->find('\StackOverflow\Question', $whichQuestionId);
            $answer = new \StackOverflow\Answer;
            $answer->setAuthor($author);
            $answer->setTitle($answerTitle);
            $answer->setContent($answerCopy);

            //THIS IS NEW!
            $answer->validate();

            //note that perhaps to take this a step futher, in the \StackOverflow\Question class 
            //I might actually call the validate function, so it's a bit more transaparent
            $question->addAnswer($answer);

            //Let's pretend we persisted everything correctly...
            //Done!

            $result->success = true;
            $result->message = 'New answer added!';

        }
        catch(Exception $e)
        {
            $result->success = false;
            $result->message = $e->getMessage();
        }

        return json_encode($result);

    }

}

Class \StackOverflow\Answer{

    //ALL NORMAL AUTO GENERATED GETTERS/SETTERS/ETC HERE

    //CUSTOM FUNCTION - perhaps called by one of the LifeCycle callback things that Doctrine has?
    public function validate()
    {
        //Look, I'm validating stuff here in my controller action           
        if(!strlen($this->getTitle()) || !strlen($this->getContent()) || !strlen($this->getAuthor()))
            throw new \Exception('Invalid answer stuff!!');

        //Notice here I'm actually doing some DB quering INSIDE of another model
        $author = $entityManager->find('\StackOverflow\User', $answerAuthorId);
        if($author->getIsBanned())
            throw new \Exception('This is user can not post answer, they are banned!');         

    }

}

Class \StackOverflow\Question{
    //Normal auto generated stuff here
}

所以我想这可能会好一点,这是用 Doctrine 做事的正确方法吗?是否可以在现有模型中调用其他模型,或者以其他方式使用 Doctrine Entity Manager?有更清洁的方法吗?

这个具体的例子非常简单,但在现实生活中我有一个类似的关系,但“答案”有更复杂和丑陋的验证,需要查找其他表,获取有关“问题”的信息以进行验证等。它还可能会更新我们示例中的“用户”,例如向问题添加新答案可能会更新用户的“问题回答”值。我宁愿这透明地发生,而不必知道它真的发生了。我想简单地添加一个问题的答案,所有验证和级联更改都会在幕后自动发生。

4

1 回答 1

1

对此没有正确或错误的答案。与控制器相比,您的模型的重量最终取决于您的选择。

我的建议是选择一种方法来做到这一点,并保持一致。

我会注意,验证应该与您正在使用的对象相关。在答案验证中检查用户是否被禁止可能不是最好的方法。相反,您应该检查与答案相关的数据是否有效。

于 2012-12-21T19:41:18.693 回答