我已经在几个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层和模型层混合成一种简化形式,它将任何真实世界类型的功能(例如用户登录)与数据访问功能相结合.
该模型类单独作为一个良好的,干净的,高保真的真实世界的实体模型.如果它是一个商业领域,它们可能是客户,计划,产品,付款,所有这些东西.您的应用程序适用于这些类.我们的想法是,您的应用程序是域对象的真实处理模型.您的应用程序可以具有看起来像人们真正做的动词的方法函数,并且这些方法函数的实现看起来像是对现实世界对象的真实描述.
重要提示:(理想情况下)这与大多数技术因素无关.它是您可以定义的域对象的最纯粹模型.[是的,你确实有外键查找问题,是的,你必须让你的模型对象知道一些数据访问组件,这样模型对象才能找到给定外键而不是实际对象的其他对象.一个好的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实现不同.
这只是一个更高抽象的问题.如果您考虑一些您即将解决的业务问题,您需要根据该业务的概念(实体,关系,流程等)来考虑它,而不是在数据库对象方面或在更详细的层面上,某些特定数据库系统(例如MySQL)的内部条款.这样,您可以根据用于实现的特定技术独立地对域(即业务及其规则)进行建模.
换句话说,当你谈论"data-access-layerish"时,你谈论表,行,数据类型,甚至是关于访问这些数据的方法(例如,通过使用Active记录模式),当你谈论域时,你谈论业务对象,业务规则和业务流程.
顺便说一下,当使用MVC模式时,你应该将业务逻辑封装在模型(域)级别(如上所述),而不是控制器 - 它们应该只触发这些规则,所以说.