当框架限制了我的想法,我选择Hack
2013-02-11 15:08
295 查看
自框架出现以来,从来就不乏这方面的讨论,比如《Java程序员的堕落》。一方面,框架大大简化便利了开发;另一方面,又因框架做了太多的封装,让我们失去了很多深入的机会,或者一旦遇到一些莫名其妙的问题就容易陷入困境。
那么应不应该使用框架?我想这个问题不是个人所能回答的。更实际的问题是,如何利用好框架?
我的web学习经历是最开始写纯粹html,接着css,不久接触web标准,随后学习js,然后不满足于静态页而开始学习php。
学习php开始很长一段时间都是用的php内嵌sql再echo html(如果不是一开始就使用框架的话,这是学习php的必经之路了),往后开始做一些项目。开始是简单的投票系统,接着是图文直播系统、网络课程,到现在的教室安排系统。规模从小到大、由简单到复杂,在这个过程中,我开始意识到,原始的php开发模式已经无法适应大量而复杂的项目了。如果不采取一些措施对代码进行有效的组织,那么光是解决一些简单而又重复的问题就可以把人累死。
借此开始接触MVC,并按照自己的理解形成了一套面向过程的MVC。有了一个简单的框架,开发变得有序多了,而且具有很好的扩展性。
回顾php的框架史,早在php具备面向对象特性之前就出现了各种框架,但并不形成气候,大多人还是宁愿使用自己的框架。直到php具备了面向对象特性,各种框架才如雨后春笋般诞生并形成了不同规模的社区。这里有个事实,面向对象的MVC框架局限性太大。就我个人来说,自己的那套面向对象MVC框架只是简单的分层而已,很多重复的工作并没有得到简化。
那么我要自己实现一个面向对象的MVC框架么,面对现在这么多php框架,为什么还要自己实现呢?
即使不是自己实现,面对现在数量如此之多的php框架还是很令人头疼的,不过想想实在没有必要过多的纠结,我本来就没打算今后只使用一个php框架,作为入门和学习我选择了ThinkPHP。
回到最初的问题,如何利用好框架,在我看来,我们应该拥抱框架(当然,根据实际情况,也有不用框架的时候),利用框架加快开发和方便维护才是实际的,但与此同时我们也要做好Hack框架的准备,有时为了突破框架的限制,我们需要采取一些特别的手段甚至改写框架源代码(这也是开源的意义不是么)。
递归的关系模型是很有价值的,并且项目中确实要用到,然而官方的RelationModel没有考虑到这点。
最坏的打算是改写ThinkPHP/Extend/Model/RelationModel.class.php,使其可以递归的处理多层关系。但阅读RelationModel的实现代码后想到,只要继承原RelationModel,并重写查询方法,对每个查询语句添加relation(true),这样通过原RelationModel,新的RelationModel就可以递归的处理多层关系了。
这是原RelationModel的源代码:
我的解决是新建一个_ReletionModel,继承自RelationModel,重写getRelation方法:
使用新的_RelationModel创建出来的数据模型就可以递归处理多层关系了。
我遇到的问题可以简单用以下代码描述:
当点击a链接,弹出的是a所指向的页面,但点击b链接还是弹出a所指向页面,这显然不是我想要的。
尝试过多种方法无果后,最后决定从bootstrap.js源代码下手。
可以看到,bootstraup的modal通过jquery的data方法存储实例化的modal对象,下次调用会判断是否已经实例化,如果已实例化,则使用已实例化的对象。
现在我需要对于不同的href重新实例化,显然,只要添加一个判断条件即可
那么应不应该使用框架?我想这个问题不是个人所能回答的。更实际的问题是,如何利用好框架?
我的web学习经历是最开始写纯粹html,接着css,不久接触web标准,随后学习js,然后不满足于静态页而开始学习php。
学习php开始很长一段时间都是用的php内嵌sql再echo html(如果不是一开始就使用框架的话,这是学习php的必经之路了),往后开始做一些项目。开始是简单的投票系统,接着是图文直播系统、网络课程,到现在的教室安排系统。规模从小到大、由简单到复杂,在这个过程中,我开始意识到,原始的php开发模式已经无法适应大量而复杂的项目了。如果不采取一些措施对代码进行有效的组织,那么光是解决一些简单而又重复的问题就可以把人累死。
借此开始接触MVC,并按照自己的理解形成了一套面向过程的MVC。有了一个简单的框架,开发变得有序多了,而且具有很好的扩展性。
回顾php的框架史,早在php具备面向对象特性之前就出现了各种框架,但并不形成气候,大多人还是宁愿使用自己的框架。直到php具备了面向对象特性,各种框架才如雨后春笋般诞生并形成了不同规模的社区。这里有个事实,面向对象的MVC框架局限性太大。就我个人来说,自己的那套面向对象MVC框架只是简单的分层而已,很多重复的工作并没有得到简化。
那么我要自己实现一个面向对象的MVC框架么,面对现在这么多php框架,为什么还要自己实现呢?
即使不是自己实现,面对现在数量如此之多的php框架还是很令人头疼的,不过想想实在没有必要过多的纠结,我本来就没打算今后只使用一个php框架,作为入门和学习我选择了ThinkPHP。
回到最初的问题,如何利用好框架,在我看来,我们应该拥抱框架(当然,根据实际情况,也有不用框架的时候),利用框架加快开发和方便维护才是实际的,但与此同时我们也要做好Hack框架的准备,有时为了突破框架的限制,我们需要采取一些特别的手段甚至改写框架源代码(这也是开源的意义不是么)。
突破ThinkPHP关系模型单层限制
最近开始使用ThinkPHP开发项目,但在使用的过程中遇到了一个小问题,ThinkPHP的关系模型只支持一层关系,这个问题其他人也发现并提出了。递归的关系模型是很有价值的,并且项目中确实要用到,然而官方的RelationModel没有考虑到这点。
最坏的打算是改写ThinkPHP/Extend/Model/RelationModel.class.php,使其可以递归的处理多层关系。但阅读RelationModel的实现代码后想到,只要继承原RelationModel,并重写查询方法,对每个查询语句添加relation(true),这样通过原RelationModel,新的RelationModel就可以递归的处理多层关系了。
这是原RelationModel的源代码:
class RelationModel extends Model { protected function getRelation(&$result,$name='',$return=false) { $model = D($mappingClass); switch($mappingType) { case HAS_ONE: $pk = $result[$mappingKey]; $mappingCondition .= " AND {$mappingFk}='{$pk}'"; $relationData = $model->where($mappingCondition)->field($mappingFields)->find(); break;
我的解决是新建一个_ReletionModel,继承自RelationModel,重写getRelation方法:
class _RelationModel extends RelationModel { protected function getRelation(&$result,$name='',$return=false) { $model = D($mappingClass); switch($mappingType) { case HAS_ONE: $pk = $result[$mappingKey]; $mappingCondition .= " AND {$mappingFk}='{$pk}'"; $relationData = $model->relation(true)->where($mappingCondition)->field($mappingFields)->find(); break;
使用新的_RelationModel创建出来的数据模型就可以递归处理多层关系了。
Bootstrap的modal无法实现不同remote的适配器
在我的项目中有一个表格,我希望通过bootstrap的modal ajax获取<a>标签href所指向的页面,简单的做法是使用bootstrap提供的DOM API,每个<a>标签的data-target指向同一个modal元素(所谓的适配器模式),这样避免了大量的js代码,却不想引入了新问题。我遇到的问题可以简单用以下代码描述:
<a id="a" data-target="#modal">a</a> <a id="b" data-target="#modal">b</a> <div id="modal" class="modal hide fade"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h3>Title</h3> </div> <div class="modal-body"></div> <div class="modal-footer"> <button class="btn" data-dismiss="modal" aria-hidden="true">关闭</button> </div> </div>
当点击a链接,弹出的是a所指向的页面,但点击b链接还是弹出a所指向页面,这显然不是我想要的。
尝试过多种方法无果后,最后决定从bootstrap.js源代码下手。
/* MODAL PLUGIN DEFINITION * ======================= */ $.fn.modal = function (option) { return this.each(function () { var $this = $(this) , data = $this.data('modal') , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option) if (!data) $this.data('modal', (data = new Modal(this, options))) if (typeof option == 'string') data[option]() else if (options.show) data.show() }) } /* MODAL DATA-API * ============== */ $(document).on('click.modal.data-api', '[data-toggle="modal"]', function (e) { var $this = $(this) , href = $this.attr('href') , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7 , option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data()) e.preventDefault() $target .modal(option) .one('hide', function () { $this.focus() }) })
可以看到,bootstraup的modal通过jquery的data方法存储实例化的modal对象,下次调用会判断是否已经实例化,如果已实例化,则使用已实例化的对象。
现在我需要对于不同的href重新实例化,显然,只要添加一个判断条件即可
…… if(!data || (options.remote && data.options.remote != options.remote)) $this.data('modal', (data = new Modal(this, options))) …… , option = $target.data('modal') && $target.data('modal').href == href ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data()) ……
相关文章推荐
- 我选择 wxWidgets 而不是 Qt 作为图形用户界面框架的一些想法
- 我选择 wxWidgets 而不是 Qt 作为图形用户界面框架的一些想法
- 我选择 wxWidgets 而不是 Qt 作为图形用户界面框架的一些想法
- [转发]在 Java Web 项目中选择使用 Slf4J 通用日志框架
- Android多张图片选择框架
- 如果是作为客户端的HTTP+JSON接口工程,没有JSP等view视图的情况下,使用Jersery框架开发绝对是第一选择。而在基于Spring3 MVC的架构下,对HTTP+JSON的返回类型也有很好
- iOS基础-UIKit框架-高级视图-UIPickerView-实例2:城市选择(列与列之间有关系)
- 前端MVC框架、类库、UI框架选择
- TensorFlow贡献者黄文坚:解读对比13个深度学习框架后的选择
- 如何进行框架的选择
- 【html5-css3游戏开发】js框架选择
- 如何选择一个Flex框架
- 关于项目SSH 框架的一点想法
- 采用 Java 持久化框架:选择、时机和优缺点?
- iOS App开发那些事:如何选择合适的人、规范和框架?
- 跨语言RPC框架Hessian、Thrift、Protocol Buffer之间的选择
- 从硬件配置到框架选择,请以这种姿势入坑深度学习
- 为什么选择Spring Boot作为微服务的入门级微框架
- 分布式网游server的一些想法(一) 语言和平台的选择
- 选择 Yii 2 框架的 7 个理由