Web框架与太阳系
古语有云:工欲善其事,必先利其器。对于Web开发亦是如此,不过现在的Web框架实在是太多了!以PHP为例,有CakePHP、CodeIgniter、Symfony,Zend,Yii等等,到底谁是最合适的?事实上过多的选择往往会让人陷入「乱花渐欲迷人眼」的窘境,这些年我一直游走在各种PHP框架之间,却始终没有觅得属于自己的屠龙刀,于是我决定自己动手,就像歌里唱的那样:不是你亲手点燃的那就不能叫做火焰。
既然要自己动手,那么就需要明确一下设计目标,我个人主要关注以下几个方面:微内核、模块化、扩展性。套用陈道明说过的一句广告语:简约而不简单。
在说明设计方案之前,不妨放松一下心情,聊聊看似风马牛不相及的太阳系:
在我小时候,课本上教的是太阳系有九大行星,分别是:水星、金星、地球、火星、木星、土星、天王星、海王星和冥王星。其中,冥王星较小,后来,人们发现还有一些和冥王星类似的天体也在围绕太阳运转,如果冥王星被划为行星的话,那么这些天体无疑也属于行星,此时太阳系到底有几大行星的问题彻底让天文学家蒙圈了,最后他们耍了一个小聪明,剥夺冥王星的行星资格就行了,从此太阳系就只剩八大行星了。
当然,我并不是让你关注这些天文学上的八卦往事,实际上我希望你关注的是太阳系的结构模式:有的行星是丁克家庭,没有卫星,比如水星和金星;有的行星是计划生育标兵,比如地球只有一个卫星(月亮);有的行星是超生游击队,卫星多的数不胜数,以至于起名时只能以阿拉伯数字加以区分,比如木星和土星。卫星沿着自己的轨道围绕着行星旋转,行星沿着自己的轨道围绕着太阳旋转,这就是太阳系!
如果你了解设计模式的话,那么你会惊讶的发现,上帝是一个设计模式大师,他在设计宇宙的结构时,使用了装饰器模式:月亮装饰着地球,地球装饰着太阳,甚至太阳系本身也是银河系的一个装饰器,如此循环,这就是宇宙!
既然上帝只用了装饰器这一个概念便创造了整个世界,那么我们能不能利用装饰器模式创造Web框架呢?实际上类似的框架在Python社区中早就有了,可惜PHP社区却好像始终无动于衷,我在几年前做过一些粗浅的尝试,但是由于种种原因搁置了,最近借着公司一个项目的改版,我终于完成了它,并命名为「Beahoo」,它是一个迷你框架,代码极简,很好的诠释了我前面提的目标:微内核、模块化、扩展性。
我们先来看看控制器中Action的代码实现:
<?php namespace Beahoo\Controller; abstract class Action { protected $decorators = array(); public function build(Action $action = null) { if ($action === null) { $action = $this; } $decorators = array(); for ( $class = get_class($action); $vars = get_class_vars($class); $class = get_parent_class($class)) { if (empty($vars['decorators'])) { continue; } foreach ($vars['decorators'] as $decorator => $name) { if (is_int($decorator)) { list($decorator, $name) = array($name, null); } if (!isset($decorators[$decorator])) { $decorators[$decorator] = $name; } } } $core = $action; $decorators = array_reverse($decorators); foreach ($decorators as $decorator => $name) { if ($name === false) { continue; } $decorator = $this->load($decorator, $action); $action = $this->build($decorator); if ($name) { $core->{$name} = $decorator; } } return $action; } protected function load($class, $args = null) { if ($args === null) { return new $class; } if (!is_array($args)) { $args = array($args); } $reflection = new \ReflectionClass($class); return $reflection->newInstanceArgs($args); } abstract public function execute( Request $request, Response $response ); }
我们再来看看控制器中Decorator的代码实现:
<?php namespace Beahoo\Controller; abstract class Decorator extends Action { protected $action; public function __construct(Action $action) { $this->action = $action; } public function getNextAction() { return $this->action; } public function getLastAction() { $action = $this->action; while (is_subclass_of($action, __CLASS__)) { $action = $action->action; } return $action; } public function execute(Request $request, Response $response) { $this->action->execute($request, $response); } }
本文省略了细枝末节的代码实现,只保留了最关键的Action和Decorator,几百行代码就实现了DNA双螺旋结构,只要有了它们,便可以衍生出丰富多彩的生命形式。
让我们扮演一把上帝,看看如何利用装饰器模式创建太阳系:
<?php namespace SolarSystem\Controller\Action; use Beahoo\Controller\Request; use Beahoo\Controller\Response; class SunAction extends \Beahoo\Controller\Action { protected $decorators = array( 'SolarSystem\Controller\Decorator\NeptuneDecorator', 'SolarSystem\Controller\Decorator\UranusDecorator', 'SolarSystem\Controller\Decorator\SaturnDecorator', 'SolarSystem\Controller\Decorator\JupiterDecorator', 'SolarSystem\Controller\Decorator\MarsDecorator', 'SolarSystem\Controller\Decorator\EarthDecorator', 'SolarSystem\Controller\Decorator\VenusDecorator', 'SolarSystem\Controller\Decorator\MercuryDecorator', ); public function execute(Request $request, Response $response) { // ... } }
装饰器本身也可以被装饰器装饰,比如地球和月球的关系就是个好例子:
<?php namespace SolarSystem\Controller\Decorator; use Beahoo\Controller\Request; use Beahoo\Controller\Response; class EarthDecorator extends \Beahoo\Controller\Decorator { protected $decorators = array( 'SolarSystem\Controller\Decorator\Earth\MoonDecorator', ); public function execute(Request $request, Response $response) { // ... } }
怎么样?是不是有种造物主的成就感,太阳系就在我们手中,设想一下:如果有一颗彗星正在穿越太阳系会发生什么情景,那么就让我们运行它试试吧:
<?php $sun = new \SolarSystem\Controller\Action\SunAction; $sun->build()->execute($request, $response);
虽然本框架在代码实现上秉承了极简的原则,但是在功能上却毫不逊色,篇幅所限,我无法一一说明,有兴趣的读者不妨自己探索一下吧。
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:老王 来源: 火丁笔记
- 标签: 太阳系
- 发布时间:2014-11-22 23:48:11
- [65] Oracle MTS模式下 进程地址与会话信
- [64] Go Reflect 性能
- [64] 如何拿下简短的域名
- [59] IOS安全–浅谈关于IOS加固的几种方法
- [58] 【社会化设计】自我(self)部分――欢迎区
- [58] 图书馆的世界纪录
- [56] android 开发入门
- [53] 视觉调整-设计师 vs. 逻辑
- [46] 读书笔记-壹百度:百度十年千倍的29条法则
- [45] 界面设计速成