MVC中数据访问层与模型的区别

时间:2008-10-13 15:13:45

标签: php model-view-controller data-access-layer

我已经在几个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图层和模型层混合成一种简化形式,它将任何真实世界类型的功能(例如用户登录)与数据访问功能相结合。

2 个答案:

答案 0 :(得分:28)

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

重要提示:(理想情况下)这与大多数技术因素无关。它是您可以定义的域对象的最纯粹模型。 [是的,你确实有外键查找问题,是的,你必须让你的模型对象知道一些数据访问组件,这样模型对象才能找到给定外键而不是实际对象的其他对象。一个好的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只是桌面版,或者只是小版本或与MVC的常见Web实现不同。

答案 1 :(得分:6)

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

换句话说,当你谈论“data-access-layerish”时,你谈论表,行,数据类型,甚至是关于访问这些数据的方法(例如,通过使用Active记录模式),当你谈到域,您谈论业务对象,业务规则和业务流程。

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