当我为一些数据库实体设计模型类(例如,一个BlogEntry为例)时,我基本上有两个选择:
“经典的OOP”方法是让类代表实体,即该类的一个实例是一个BlogEntry.在CodeIgniter中,这将导致代码
class Blogentry extends CI_Model { function load($id) { // Access database $this->id = $dbresult.id; $this->title = $dbresult.title; $this->author = $dbresult.author; } }
要访问某些博客条目,我将执行一个$this-> load->模型(‘blogentry’);调用$this-> blogentry-> load($id),然后使用模型类实例.
我经常在野外看到的另一种方法是让模型在一些数据结构中返回实体.在代码中:
class Blogentry extends CI_Model { function get_entry($id) { // Access database,yielding $dbresult return $dbresult; }
有了这个我会写
$this->load->model('blogentry'); $the_entry = $this->blogentry->get_entry($id);
在控制器中并与$the_entry一起工作.在第二种情况下,该类更像是@L_301_2@或builder类.
这两种方法中有哪一种被认为是在MVC中做M的“正确方法”?我认为,我经常看到第二种方法,但是我并没有看到很多MVC-Webapps.任何想法,为什么第一种或第二种方法可能更合适?
在古典/传统MVC(不是框架声称是MVC)中,模型不是类或单个文件,而是包含所有域名业务逻辑的层,通常只由Domain Objects,Data Mappers,以及处理调用实体和域逻辑之间的接口的东西,以便将这些代码保留在控制器之外(例如在MVC中). Tereško names them “services”,这是一个准官方的名字.
因此,在传统的MVC中,通过“服务”向模型层请求,从而与域对象和数据映射器进行交互.
显然所有这一切与CodeIgniter和其他框架称为“MVC”几乎没有关系.在这种设计模式(简称CIMVC)中,Model是由Controller调用和操作的类,并直接与数据库进行交互.将数据存储在模型中的成员变量中并不会产生很大的语义意义,但如果您对类似的内容感兴趣,请查看CIMVC中编写的任何ORM插件/库. (尽管ORM解决方案不符合传统的MVC …)
对于常见做法,我看到的大多数CI应用程序将“原始”数据库数据返回给控制器进行处理;这将域业务逻辑保留在模型中.我在CIMVC中的个人喜好是减少/消除模型中的域业务逻辑.
tl; dr – “传统/正确”的CodeIgniter中的MVC基本上是不可能的,所以试图强制您的CI代码符合传统的MVC范例是愚蠢的(并且可能会驱使你疯狂)
编辑:为了澄清一些关于模型层中业务逻辑的混淆,是的,你应该在模型层中拥有所有的业务逻辑.但是,如果有额外的数据处理(排序,操纵等),现在我们进入危险的领域以进行DRY和SRP的违规行为;您希望模型可重用,因此请谨慎添加这么多或这样专门的逻辑,使其在应用程序的其他部分变得不可用.