AOP?原来我们早就见过
最近在学习Spring,深深地感到这个框架之所以这么流行不是没有道理的,我之前一直用的是PHP,框架用的就是codeigniter,由于其简洁轻量的特性很是让人喜爱,可是也有很多问题,然而很多问题Spring都是解决了的,比如
PHP项目中CodeIgniter使用的一些建议,这里提到的登录逻辑的实现,就是具有Spring 面向切面编程 的雏形。所以刚看到Spring的面向切面编程(AOP),就觉得:原来我们早就见过。其本质上就是关注点的分离,可以清晰的分离不同的业务逻辑,既提高了开发效率(不同的逻辑由不同的人并行书写),也利于代码维护(不用寻找遍布整个项目的log,或者验证代码)。
在codeigniter中实现切面的方法:即可以如上文中所说的扩展CI 核心类的方法,也可以采用钩子(hook),详见: 钩子 - 扩展框架核心
MVC?反哺Codeigniter
在使用Codeigniter经典的MVC模式进行开发的时候,享受到了许多便利,业务逻辑(C)、数据存储(M)、视图(C)分开,这样结构很清晰,思路也很自然。但是也遇上了一些问题,比如我在写后端的时候通常是面向两个前端的:一个是移动APP,一个是网站。这两者通常会有一些业务逻辑的重合,比如都会显示一些新闻列表(list),通常的做法是使用两套个模块,如图
api是面向移动APP的,他的list方法就是
$this->load->model ( 'api/Box_model','boxm' );
$data = $this->boxm->getRec ( $startCount, $perNumber );
echo_json ( $data );
web是面向网站的,他的list方法就是
$this->load->model ( 'web/Box_model','boxm' );
$data= $this->boxm->getRec ( $startCount, $perNumber );
$this->load->view ( 'web/list', $data );
这样的话就相当于控制器写了两次,模型也写了两次,而且好多CtrL+C,CtrL+V。其实出现了这么多CV
代码,就该知道这样的架构是不太合理的,因为需求变化的时候改了一处,还得CV到另一处去...... 而Spring的学习让我看到了解决这个问题的方法,就是要学会抽离逻辑,把真正的业务逻辑和视图逻辑分开,也就是把三层的MVC分成 View - Controller - Service - Repository 四层,其中Repository负责数据存储,Service负责真正的业务逻辑,Controller负责与用户界面有关的逻辑,View负责与用户交互。
这样上面的代码就可以改为
api
$this->load->service('list_service');
$data = $this->list_service->getRec ( $startCount, $perNumber );
echo_json ( $data );
web
$this->load->service('list_service');
$data = $this->list_service->getRec ( $startCount, $perNumber );
$this->load->view ( 'web/list', $data );
这样统一让Service去和业务逻辑打交道,Controller是需要用数据来和不同的用户界面打交道(一个是返回json数据,一个是渲染HTML页面)。业务逻辑发上变化的时候只需要修改一个Service就可以了。
那么怎么在Codeigniter中实现这个功能呢?这篇文章说的很清楚了,让CI框架支持service层
简单说来就是
首先自己定义一个Service类,注意一定要加上
$this->CI =& get_instance();
,这才能保证你可以在Service类中加载CI的各种资源,比如模型,辅助函数和库然后修改CI的加载器,使得
$this->load->service('list_service');
这一句代码是可行的,这里的代码可以模仿CI 原生的加载器来写,比如在/system/core/Loader.php
中的function helper()
就是$this->load->helper('url');
可行的原理最后就可以在Controller中调用不同的Service,Service中调用不同的model了。
后记
设计模式也是与时俱进的,在只有web一种终端的上个世纪,MVC模式是足够的,然而现在各种终端出现,MVC也会产生许多问题(当然这只是一个原因),于是新的模式出现了,所以经典的要学,更新的也要看,常常思考项目中的问题,说不定自己也能搞一个设计模式出来(哈哈~)。
欢迎访问我的个人主页 mageek(mageek.cn)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。