转:ZendFramework中领域逻辑的处理

ZendFramework一直为人所诟病的缺点就是不能优雅的处理领域逻辑,这里谈谈我的一些解决思路:

先看看一般情况下我们都是怎么写Model,Controller的:

Model的一般写法:

class Articles extends Zend_Db_Table 



Controller的一般写法:

class ArticlesController extends Zend_Controller_Action 

    protected $_articles; 

    public function init() 
    { 
        $this->_articles = new Articles(); 
    } 

    public function createAction() 
    { 
        $article = $this->_articles->createRow(); 

        $article->title   = 'abc'; 
        $article->content = 'xyz'; 

        if ($id = $article->save()) { 
            $this->_redirect('...'); 
        } else { 
            // ... 
        } 
    } 

    public function readAction() 
    { 
        $this->view->article = $this->_articles->fetchRow("id = 1"); 
    } 

    public function updateAction() 
    { 
        $article = $this->_articles->fetchRow("id = 1"); 

        $article->title   = 'abc'; 
        $article->content = 'xyz'; 

        if ($article->save()) { 
            $this->_redirect('...'); 
        } else { 
            // ... 
        } 
    } 

    public function deleteAction() 
    { 
        $article = $this->_articles->fetchRow("id = 1"); 

        if ($article->delete()) { 
            $this->_redirect('...'); 
        } else { 
            // ... 
        } 
    } 


通常我们说:Rich model is better。在上面的例子中可以明显看出:Model代码很少,Controller代码很多。一般来说这是坏味道的前兆,不过上面的CRUD例子比较简单,而且Model通过继承获得了一定的CRUD能力,也可以说是很Rich的,所以这个问题并不要紧,真正的考验是当应用包含大量的逻辑的时候怎么办。

所谓逻辑大致分两种,一种是应用逻辑,一种是领域逻辑。对一个文章对象来说,文章添加成功后发送一封邮件通知就属于应用逻辑,而怎么判断是不是热门文章就是领域逻辑。

应用逻辑和领域逻辑划分的原则就是看是否有技术的味道。有就是应用逻辑,没有就是领域逻辑。之所以这样划分是因为面向对象强调重用性,而领域逻辑是一个软件的灵魂所在,只有剥离了技术味道才有更大的重用可能性。

在ZendFramework里,我们可以把Controller看作是应用层,因为它自然的勾画了用例,所以把应用逻辑放在Controller里是说得过去的,而领域逻辑则无论如何要保证百分百在Model里。在通常的ZendFramework代码里,Model的角色一般是由Zend_Db_Table来扮演的。Zend_Db_Table属于一个表数据入口的实现。表数据入口是操作一个表的模式,而我们的对象往往只是一个行,所以很多领域逻辑不太可能加在Zend_Db_Table的层次上,而应该是Zend_Db_Table_Row的层次。

下面看如何把领域逻辑融合到Zend_Db_Table_Row中:

首先自定义一个Row类:

class Article extends Zend_Db_Table_Row 

    public function isHot() 
    { 
        // ... 
    } 


然后让Row类能挂接到Table类之上:

class Articles extends Zend_Db_Table 

    protected $_rowClass = 'Article'; 
}


这个时候,就可以通过Row类来使用包含领域逻辑的方法(比如:isHot方法)了:

$article = $this->_articles->fetchRow("id = 1"); 

if ($article->isHot()) { 
    // ... 
} else { 
    // ... 
}


我上面所做的一切的一切,目的只有一个:就是要把Zend_Db_Table_Row变成Rich Model!

在ZendFramework的使用中。我们可以把Zend_Db_Table当作管理领域对象生命周期的工厂或仓储使用,它里面可以有少量和领域对象生命周期相关的逻辑,比如说领域对象的组装等等。更多领域逻辑存在于Zend_Db_Table_Row对象中。

一般的操作流程应该是这样的:Zend_Db_Table里通过fetchRow或者fetchAll方法得到Zend_Db_Table_Row或者Zend_Db_Table_Rowset。然后使用Zend_Db_Table_Row去完成领域逻辑。

如果你的实体很多,挨个自定义Row类似乎很是乏味,要是ZendFramework能像CakePHP那样提供脚手架去自动生成代码就爽歪歪了,不过这是不可能的事情了。ZendFramework和CakePHP的指导思想迥然不同,走的完全是两条路。

转自:http://hi.baidu.com/thinkinginlamp/blog/item/0637d0166fbb851c972b4390.html

转载于:https://www.cnblogs.com/mahy/archive/2012/02/01/2334797.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值