我应该完全分离MVC中的模型和ORM吗?



我正在PHP中开发一个不使用任何框架的MVC应用程序。我使用RedBean作为我的ORM,它实现了数据映射器模式,并且与doctrine非常相似。

根据这个问题,我理解模型不是ORM对象。在我的项目中,我有以下场景:

  • 需要与数据库中大量表对话的"复杂"模型:

      其中一个模型可以是类似RBAC权限系统的东西。控制器应该能够调用$permission->isAllowed($controller, $action, $resource)之类的东西来确定是否允许用户执行请求的操作。此外,他可能调用$permission->getPermissions()来获取用户拥有的权限列表。
  • "简单"模型,模型一般可以用数据库中的1个表来表示:

    • 其中一个模型是User模型。如$user->changeRank()$user->addPoints()等。
  • 我现在面临的问题是,查看各种框架的大多数文档,我可以看到在示例中,控制器直接与ORM对话。例如,下面是symfony2中的一个示例控制器:

    public function createAction()
    {
        $product = new Product();
        $product->setName('A Foo Bar');
        $product->setPrice('19.99');
        $product->setDescription('Lorem ipsum dolor');
        $em = $this->getDoctrine()->getEntityManager();
        $em->persist($product);
        $em->flush();
        return new Response('Created product id '.$product->getId());
    }
    

    如果ORM不是模型,为什么允许控制器直接与它交互?它不应该与这样的模型交互吗?

    class ProductModel{
       public function newProduct($name, $price, $description){
            $product = new Product();
            $product->setName('A Foo Bar');
            $product->setPrice('19.99');
            $product->setDescription('Lorem ipsum dolor');
            $em = $this->getDoctrine()->getEntityManager();
            $em->persist($product);
            $em->flush();
       }
    }
    

    最后,我前面概述了permissions模型。这被认为是MVC上下文中的模型吗?该类将在整个应用程序中使用,因为大多数操作都需要检查访问权限。

    ORM(对象关系映射器)用于生成模型文件。模型文件用于在应用程序和数据库(模型)之间进行通信。看起来你很精通ORM过程,但是对于那些可能不熟悉的人来说,快速回顾一下(以原则为例),我可能会很幸运地回答你的问题。

    您使用ORM来内省您的数据库模式,这将生成一个模式文件。现在有了这个模式文件,您可以根据应用程序的需要对其进行修改。例如,可以添加actAs: { Timestampable ~}actAs: NestedSet: hasManyRoots: true。此外,您将希望使用这个模式文件来设置对象之间的关系如何表现(例如,使用refClass的1:M, M:M,等等)

    一旦您的模式文件准备好了,您就可以发出命令来生成模型文件。模型文件是类,您可以在应用程序中使用这些类来访问数据库。因此,控制器实际上是通过ORM生成的文件与模型(您的数据库)进行通信的。

    您给出的示例是一个很好的示例,因为您可以将大部分业务逻辑从操作(页面控制器)中卸载到模型中。通过这种方式,可以从其他代码点访问相同的逻辑,而不必处理任何控制器级逻辑。doctrine所做的(以及propel所做的)是允许你创建"Table"(或"Peer")类。这些类充当处理多个对象的容器。您应该在这些类中添加业务逻辑,如第二个示例所示。

    最终的目标是保持你的动作尽可能轻量,只处理请求参数和表单处理,然后通过"表"或自定义类你设计推值到你的模型。按照这个范例,您可以拥有一个功能丰富的应用程序,它具有精简的操作和集中的业务逻辑。

    编辑,

    对不起,我错过了你关于你的权限API的最后一个问题。从你发布的内容来看,它似乎遵循MVC范式,因为你有一个权限对象,并且正在使用控制器和数据库之间的API。

    最新更新