`
阿尔萨斯
  • 浏览: 4187032 次
社区版块
存档分类
最新评论

聊聊Zend Framework中Front Controller的Singleton实现

 
阅读更多
作者:老王

有句老话儿说:尽信书不如无书。写程序也是一样,不仅要知其然,更要知其所以然,并不是照搬几个设计模式就显得更有技术含量。今天我打算聊聊Zend Framework中Front Controller的Singleton实现,阐述一下存在的问题。

先说说什么是Singleton?

所谓Singleton是指某个类只实例化一个对象。有的时候是因为客观情况需要这样的限制,比如说Windows操作系统里只有一个回收站实例;更多的时候是因为Singleton可以避免类被频繁的实例化,从而提高效率。

下面看看Java框架里(struts,spring)的一些例子代码:

struts:
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response
) throws Exception;

spring:
public ModelAndView handleRequest(
HttpServletRequest request,
HttpServletResponse response
) throws Exception;

这些代码有一个共同的特点,就是把request,response统统作为方法参数,而不是作为对象属性。为什么要采用这样的方式呢?是因为通过剥离request,response等因素,相关对象变成为无状态对象,然后通过Singleton便可以在各个请求之间重复使用对象实例。

下面回到Zend Framework上来,从文档上,我们可以看到Zend_Controller_Front的Singleton描述:

Zend_Controller_Front also implements the Singleton pattern, meaning only a single instance of it may be available at any given time. This allows it to also act as a registry on which the other objects in the dispatch process may draw.

相关代码:

$front = Zend_Controller_Front::getInstance();

看上去很美。可惜做错了。因为我们用的是PHP,而不是Java。在Java中,一个Singleton的对象不仅可以在同一个请求中被重复使用,还可以在不同的请求中重复使用。而在PHP中,每一次请求中,运行环境都需要重新建立,所以说在PHP中,Singleton的使用范围相对而言是窄一些的,只能在同一个请求中重复使用。Zend_Controller_Front作为Zend Framework中的前端控制器,在同一个请求中本来就只需要实例化一次,所以它不存在重复使用的需求,自然就不应该使用Singleton。在这样的情况下如果还去生搬硬套,结果就好像是穿着西装去打篮球一样,虽然衣着很帅,但却不合时宜。

补充:很多网友提醒我,在ZendFramework中是存在Zend_Controller_Front的复用的,如helper, plugin等等,我不否认ZendFramework存在这样的用法,但是我认为这也是不对的,至少是不好的。与其说是复用Zend_Controller_Front,其实是为了复用Request,Response这些对象,但从道理是来说,这些对象应该多以对象属性或者方法参数的方式传递才好,生硬的在方法内部通过静态调用Singleton方法的方式去复用,不仅不优美,并且也没有机会去Mock,存在很多弊端。归根到底还是那句话,对一个PHP请求来说,是不存在前端控制器的复用的。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics