6

我正在用 PHP 编写自己的 MVC 框架,仅用于学习目的。拥有一个路由器/调度程序类来调用正确的控制器/动作等并不难。

但现在我正处于我将要使用模型的部分。或者实际上,模型层。但是有一点让我很困惑。

许多其他 MVC 框架都有一个“BaseModel”。我读过这实际上是不好的做法,因为“模型”不应该被视为另一个类。但作为一个真正的“层”,它可以包含“映射器”模式或“存储库”模式等。

但老实说,我看不出这有什么好处。对我来说,“BaseModel”课程似乎是最快的方法,结果相同。

我可以简单地做类似的事情:

class User extends BaseModel
{
    // the GetUserBy* could easily be something that's handled by the
    // BaseModel class, like in the Repo pattern.

    public function getUserByName ( $name )
    {
        // no error handling of any kind, just for simplicity
        return $this->db->exec("SELECT * FROM users WHERE name='".$name."'");
    }

    // $data = array
    public function saveUser ( $data )
    {
        // Make sure no extra fields are added to the array
        $user = array ( 'name' => $data['name'],
                        'address' => $data['address']);

        $this->db->autoSave ( $user );
    }
}

但是,如果我选择存储库模式,那么我必须创建以下内容:存储库实体 DAO

实体具有到其他存储库的聚合。所以基本上我正在手动将我的整个数据库方案写出到对象......

最后,有什么区别???除了我可能只需使用 BaseModel 类就可以节省很多时间......

但是为什么它仍然被认为是一件坏事呢?并不是说 repo 模式比我现在做的更能解耦我的应用程序。因为对我来说,上面提到的那些模式似乎被高估了。它可能只适用于具有共享状态的应用程序;将对象保存在本地(在存储库中)并稍后提交。

这就是为什么我认为没有人能真正回答这个问题......

但我仍然希望看到一个体面的答案让我走:“啊……我在想什么……”。但如果不是,那么我确信 BaseModel 根本不是一件坏事,而且大多数博主只是一群羊 :-)

4

4 回答 4

1

并不是说 repo 模式比我现在做的更能解耦我的应用程序

您的应用程序与 SQL 数据库组件(实际上充当映射器)紧密耦合。然而,尽管如此,你的设计更像是一个存储库,而不是一个Active Record方法(这可能是你提到的大多数博主所抱怨的)。

活动记录不仅封装了数据,还封装了数据库访问:

$user = new User();
$user->setUsername('jane');
$user->setEmail('jane@foo.bar');
$user->save();

最好让记录对象不知道持久层(关注点分离)。您的“基础”通过返回用户数据数组来做到这一点,当这些数组被修改时,必须将它们传递回用户“基础”进行保存。您可以将命名更改为:

class UserRepo extends BaseRepo
{
    // user-specific repo code...
}

$userRepo = $this->getRepo('User');
$user = $userRepo->getUserByName('jane');
$user['email'] = 'jane@new.email';
$userRepo->save($user);

拥有基础回购没有任何问题。

于 2012-04-23T17:24:23.327 回答
1

如果你试图从 PHP 框架中学习好的 MVC 实践,那么你做错了。即使是最好的 PHP 框架也充满了设计错误和缺陷。

具有“BaseModel”的框架通常正在实现某种 ORM。这里最流行的模式是 ActiveRecord。这对于简单的表来说很好,与其他表没有关系(基本上 - 美化的 getter/setter)。但是在处理更复杂的结构和查询时开始崩溃。通常会造成大量的技术债务

这种方法导致问题的另一个原因是,在这种情况下,您的“模型”有太多的责任。您的业​​务逻辑与存储紧密绑定,存储与逻辑紧密相连。随着应用程序的增长,这样的“模型”将积累黑客。

不,“一群博主”不是羊。他们只是阅读了有关应用程序架构和面向对象编程的书籍。你上一次读这方面的书是什么时候?

于 2012-04-24T21:29:14.173 回答
0

我根本不会使用基本模型,因为您的大多数模型都没有应该遵循的统一接口。如果您愿意,您可以为许多不同类型的模型(这只是基本的面向对象编程)创建一个基类。

总的来说,我相信模型应该是“松散”的组件,您可以将它们与控制器连接在一起并以一个或多个视图显示。它们不能真正拥有统一的接口,因为它们都会做不同的事情:有些甚至可能不与持久性存储对话,有些可能不是持久的,和/或有些可能由其他模型组成。

于 2012-04-23T16:46:06.883 回答
0

Model类应该是抽象的,只定义方法而不实现它们。至于您的User模型,您可以轻松编写一个GettingUsers具有所有这些功能的接口,并在User模型上实现它。

于 2012-04-23T15:33:24.027 回答