2012-04-23 39 views
6

我正在用PHP编写我自己的MVC框架,仅用于学习目的。有一个路由器/调度员班级调用正确的控制器/操作等并不是很难。PHP MVC中的BaseModel,好还是坏?

但现在我在我要使用模型的部分。或者实际上,模型层。但有些事情让我感到困惑。

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

但是说实话,我没有看到任何优势。对我来说,一个'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类节省大量时间...

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

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

但我还是希望能看到一个像样的答案,让我走:“哈啊......我在想什么.... ”。但是,如果没有,那么我肯定我的情况是,BaseModel并不是一件坏事,而大多数博主都只是一堆羊:-)

+1

看起来很漂亮[推进](http://www.propelorm.org/)-ish – Alp 2012-04-23 15:34:51

+2

你能给我们一个链接到这些博客文章之一? – webbiedave 2012-04-23 16:19:40

+1

@Alp的代码示例? Propel只是一个ORM,我不会朝这个方向前进,因为我喜欢自己写查询。我不重新ORMs。但我宁愿不要使用它们。有些'魔术'可以,但不是太多。但那是另外一个故事。 – Vivendi 2012-04-23 16:22:19

回答

1

它不是回购模式解耦我的应用程序更多然后我 现在做

您的应用程序是紧耦合到SQL数据库组件(这是,实际上,作为你的映射器) 。然而,尽管如此,你的设计更像是Repository而不是Active Record的方法(这可能是你引用的大多数博客都在持续的)。

活动的记录,不仅可以封装数据,而且数据库的访问:

$user = new User(); 
$user->setUsername('jane'); 
$user->setEmail('[email protected]'); 
$user->save(); 

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

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

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

有一个基本回购没有任何问题。

+0

我想你是对的。它看起来像某种方式的回购模式。但我没有使用任何实体类或值对象。就像我在我的文章中所说的那样,这感觉很像将数据库方案重写为“对象”。 ---我的'UserRepo'只是直接从SQL查询中返回数组。我没有看到Entities/VO的使用。因为如果我使用实体我基本上说,给我我的结果作为我的查询数组,将它们映射到我的实体对象,并使用它来获取/设置数据。我不明白为什么我应该浪费时间(实体)。对此的任何想法......? – Vivendi 2012-04-23 18:10:30

+0

将你的记录映射到对象允许他们所有的OOP选项,如果你需要它们(一个定义的结构,接口,类型提示等)。基于数组的更快,使用更少的资源,并且可以将它们传递给本地PHP数组函数。这是一种折衷,这完全是你的呼叫。 – webbiedave 2012-04-23 18:28:27

0

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

+2

这是一个非常书籍化的答案,并没有任何陈述后续与一个体面的解释为什么这样。此外,如果模型类只定义没有任何实现逻辑的方法,那么它应该是一个接口,而不是抽象的。就像我说的,我知道我可以“轻松”将它分成模型,抽象类,接口。但是*什么*与单纯的BaseModel相反。它看起来像你甚至没有试图回答这个问题。 – Vivendi 2012-04-23 16:14:52

+1

@Vivendi - 有趣的问题,但请民事。正如代表所证明的那样,真相已经存在了一段时间,而你在这里是新的。 – halfer 2012-04-23 16:56:01

+1

@halfer对不起,我希望没有人对我的回复采取任何冒犯行为。无论如何,我的意思不是粗鲁。我应该以不同的方式在我的评论中陈述某些事情。 – Vivendi 2012-04-23 18:13:28

0

我根本不会使用基本模型,因为大部分模型都没有统一的接口,它们应该符合。如果你愿意的话,你可以为许多不同类型的模型创建一个基类(这只是基本的面向对象编程)。总体而言,我相信模型应该是“松散”的组件,您可以将它们与控制器连接在一起,并显示一个或多个视图。他们不可能有一个统一的界面,因为他们都会做不同的事情:有些甚至可能不会与持久性存储对话,有些可能不会持久存在,或者有些可能由其他模型组成。

1

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

有“BaseModel”的框架通常实现某种ORM。这里最流行的模式是ActiveRecord。对于简单的桌子来说很好,与其他人没有关系(基本上是荣耀的getter/setter)。但在处理更复杂的结构和查询时开始出现故障。通常造成广泛的technical debt

另一个原因,为什么这种方法会导致问题,因为在这种情况下你的“模型”可能有责任。您的业​​务逻辑与存储密切相关,存储与逻辑相关联。随着应用程序的增长,这些“模型”将会累积黑客。

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

+0

我正在阅读很多矛盾的东西:)。但是,你会怎么做,所以你不会在模型中积累太多?看起来你要么有胖的模特,胖的控制者,某处的图书馆,存储过程等等。你是做什么?由于许多复杂的查询,我必须避免ActiveRecord的想法。 AR感觉像一个黑客,变得巨大。我也喜欢SQL,然后紧密耦合我。谢谢。 – johnny 2014-08-25 14:46:50

+0

@johnny我认为你的主要问题来自于有关“模型”究竟是什么的糟糕信息。也许[这篇文章](http://stackoverflow.com/a/5864000/727208)帮助了一下。 – 2014-08-25 15:02:46