MVC 中数据访问层和模型之间的差异

我已经在几个Web应用程序中实现了我认为相当不错的MVC表示形式,但是自从加入crackoverflow以来,我发现也许我最初的定义有点简单,因此我真的很想澄清一下数据访问层与Web应用程序的模型或域层之间的差异。

对于上下文,我目前使用数据访问对象,这些对象为对象表示的表中的单个记录实现 CRUD 函数,以及返回一个对象的 get() 函数,该对象允许我循环访问满足 get() 函数条件的所有对象。

这些数据访问对象直接从包含我的业务逻辑的控制器脚本中引用。

如果这很重要,我正在使用PHP和MySQL,但我对可能用其他语言编码的建议感兴趣。

更新:对于更具体的例子,我有一个名为user的表(这里的约定是单数表名),其中包含诸如电子邮件地址,活动状态,用户名,密码,它们所属的公司等信息。此基本对象在代码中如下所示:

class User implements DataAccessObject
{
     protected $user_id;
     protected $email;
     protected $username;
     protected $password;
     protected $company_id;
     protected $active // Bool that holds either a 0 or 1

     public function __construct ( $user_id ) // Uses Primary Key to know which record to construct
     {
          $sql = //Sql to get this information from the database.

          // Code necessary to assign member variables their values from the query.
     }

     public function insert(){}
     public function update(){}
     public function delete(){}
     public static function get($filters, $orderVals, $limit){}

     // An object such as user might also contain the following function definition
     public static function login($username, $password){}
}

听起来我可能已经将DAO层和模型层混蛋化为简化的形式,将任何实际类型的功能(例如用户登录)与数据访问功能相结合。


答案 1

模型类独立地作为真实世界实体的良好、干净、高保真度模型。如果它是一个商业领域,他们可能是客户,计划,产品,支付,所有这些东西。您的应用程序使用这些类。这个想法是,您的应用程序是域对象的实际处理的模型。您的应用程序可以具有看起来像人们真正做的动词的方法函数,并且这些方法函数的实现看起来像对真实世界对象的真实描述。

重要提示:这(理想情况下)独立于大多数技术考虑因素。它是您可以定义的域对象的最纯粹的模型。[是的,您确实存在外键查找问题,是的,您必须使模型对象了解某些数据访问组件,以便模型对象可以在给定外键而不是实际对象的情况下找到彼此的对象。一个好的ORM层会为你处理这个导航问题。

充满SQL的模型不是一个好的模型。现实世界中也没有充满SQL。发票是一份文件,其中包含一些名称,地址和项目,发货日期以及一堆类似的东西。

访问类处理持久性存储。这通常包括将模型对象映射到关系数据库表。面向 SQL 的数据访问层将从关系数据库重建模型,并将模型保留在关系数据库中。YAML 数据访问层将从模型中读取和写入 YAML 文件。

有时,对象关系映射 (ORM) 设计模式用于在 SQL 的世界和模型之间进行清晰的分离。有时,数据访问对象 (DAO) 处理 SQL 和模型之间的这种分离。ORM 或 DAO 对象可以装满 SQL。

事实上,当您更改数据库产品时,一的变化是在DAO或ORM中。该模型永远不会改变,因为它独立于SQL,YAML,JSON,XML或其他一些序列化技术。

如果你的DAO创建并持久化了模型对象,我认为你已经很好地实现了MVC的模型部分。您可以查看ORM软件包,以获得最先进的其他想法。我自己就是iBatis的粉丝。

但这只是整个MVC世界观的1/3。当然,纯粹主义者会告诉你,MVC只是桌面或只是smalltalk,或者与MVC的常见Web实现不同。


答案 2

这只是一个更高抽象的问题。如果您要解决某些业务问题,则需要根据该业务的概念(实体,关系,流程等)来考虑它,而不是根据数据库对象或更详细的级别,根据某些特定数据库系统的内部(例如。MySQL)。通过这种方式,您可以根据用于实现的特定技术独立地对域(即业务及其规则)进行建模。

换句话说,当你谈论“数据访问分层”时,你谈论的是表、行、数据类型,甚至是访问这些数据的方法(例如,通过使用活动记录模式),而当你谈论域时,你谈论的是业务对象、业务规则和业务流程。

顺便说一句,在使用MVC模式时,您应该将业务逻辑封装在模型(域)级别(如上所述),而不是控制器中 - 它们应该只是触发这些规则,可以这么说。


推荐