17

我已经在几个 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 层和模型层混为一谈了,它结合了任何现实世界类型的功能(例如用户登录)和数据访问功能。

4

2 回答 2

30

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

重要提示:这(理想情况下)独立于大多数技术考虑因素。这是您可以定义的最纯粹的领域对象模型。[是的,你确实有外键查找问题,是的,你必须让你的模型对象知道一些数据访问组件,以便模型对象可以找到只给定外键而不是实际对象的其他对象。一个好的 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 实现不同。

于 2008-10-13T15:40:50.283 回答
8

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

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

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

于 2008-10-13T15:43:01.807 回答