如标题所示,最近这两个月学着用PHP写了个东西,顺道产出了一个框架:zero-framework。 其实用PHP写东西这个事情去年就开始了,期间研究过typecho,体验了ThinkPHP还有两三个非常粗糙的所谓的极简框架(比我的zero-framework还要粗糙)。在多番折腾后最终用CodeIgniter写了一个CMS应用。 总体来说,CodeIgniter的轻量级和灵活性还是非常对我的胃口的。但是有两个地方不太容易接受:数据库操作上的种种自以为是和对IDE(PHP Storm)的不友好。尤其是后者,每次想查看一个方法的代码时都无法自由跳转实在是让人憋闷。所以后来干脆用java把整个功能又重新实现了一遍。 本来以为事情就这样了,但是维护VPS运行环境实在不让人省心,加上php虚拟主机的诱人价格,所以又将目光转回了PHP。不过这次我计划不使用任何框架,直接使用原生的PHP。另外也隐约想到在我的产品完成的时候,也许会产生一个框架。毕竟所谓框架最初也只是开发习惯的一个集合而已。 在整合了路由功能和数据库操作能力后,框架的雏形就已经有了。随着开发的进展、结束以及上线,zero-framework逐步成形——按我期望的样子。受CodeIgniter影响颇深,此外也不能说没有Java SpringMVC的作用,zero分成了Controller / Service / Model三层,也就是网络/业务/数据库三层。为了能在IDE中清晰地追踪方法调用,每层的对象都是显示创建的。显式创建对象这个事情并不是一种好的方案,而像ci那样通过load来避免重复创建对象会更好些。但是为了对IDE更友好些,最终采用了前者,因此在开发时也需要格外注意减少对象重复创建。zero的数据库操作使用了ActiveRecord的形式,不止提供了常规的快捷操作方案,也支持自定义SQL灵活查询。此外因为有多主题的需求,提供了主题切换方案。zero也就是这些特点了。毕竟初学PHP,而且只使用它完成了一个相对较小的需求,zero肯定有许多不完备的地方。 zero-framework的项目地址在 GITHUB/zero-framwork。基于zero完成的产品是 Buffalo,一个小说网站或CMS网站。有和我面临同样需求的同学可以参考下,毕竟有源码也有实例不是。 再聊些对PHP的看法,先夸优点:PHP不愧是最好的编程语言,入门相对简单(初学者就能产出一个框架),天生对WEB非常友好,类脚本语言修改和调试起来都非常简单快捷,应用hook可以灵活地实现AOP操作。不足之处是它提供的魔术方法很容易被滥用,弱类型语言也比较难得到IDE的充分支持,此外就是debug的繁琐了,PHP缺少一个足够好用的debug工具。另外作为一个Javaer,刚开始使用PHP时,对于内存操作这块儿充满了各种疑问。 也就这些可以说说了。最后还想废话一下:因为洁癖或者说是习惯就抛弃既有的成熟框架,反而花费大量时间和精力去造一个新的轮子,这并不是一种值得提倡的做法。但是人生苦短,代码既然能让我得到一点快乐,为何不稍稍允许自己任性一点呢。
[阅读更多...]-
一个极简的PHP框架:zero-framwork
-
关于代码重构那些事
首先抛出观点:重构既有代码并不是一件讨好的事情,甚至是一件无功有过的事。 说个我朋友的事(我的一个朋友系列)。这个人颇有些强迫症。他在入职某家公司一段时间后,实在受不了负责模块那些祖传代码的组织方式,就用工作之余的的时间彻底重构了部分内容。也算幸运,他的重构工作没有影响生产业务。在年底进行绩效评估的时候,他将代码重构作为绩效的一部分汇报,却没有得到领导的认可。为什么呢?因为即使没有重构,以前的代码也能满足业务需求,而且重构后的代码并没有性能上的显著提升,他的工作被视为是可有可无的。 对于朋友的做法,我现在说不上不认可;对于当时他的领导的做法,我也能够理解。如果对代码进行重构的肇始是缘于洁癖或强迫症,那么最好三思三思三思而后行,至少也不要一开始就全面重构。因为既有的祖传代码虽然可能比较糟糕,但还是经过了生产业务的考验的。而修改后的代码必须得经过充分的测试才能投入生产。而这种测试我不认为是开发一个人进行自测就能充分覆盖完全的,项目组需要为这些改动多投入一些成本。 但是重构就是完全不能进行了么?我也没这么说。我只是强调了要优先保证生产环境的稳定性,并且需要顾及到团队投入的成本。重构还是要做的,但是要掌握好契机。 比如有新需求来的时候,如果继续用过往的代码适配新的业务逻辑会消耗太多的时间。这些时间甚至超过了重构的时间。那么此时优先选择重构。 再比如发现引入新的技术方案可以显著提升当前系统的性能,改善系统的短板。那么经过团队讨论后,可以在引入新方案的时候顺手实现代码的重构。 充分利用这些机会,就可以在不会过多占用团队资源的前提下,重构既有代码。 如果没有理想的机会的时候也可以小范围的进行调整,或者拉一个新的分支在不影响生产系统的前提下实现对既有代码的改造。这样在真正需要大面积改造的时候也就有了足够的基础。
[阅读更多...] -
关于Scrum敏捷开发的一点想法
公司中层最近开始推scrum敏捷开发,落实到行动上大概有这么几个方面: 定期迭代,小步快跑; 产品经理创建Backlog(需求列表); 团队进行需求评审; 开发团队组织会议,对需求进行细化,分解成一个个可以执行的具体任务(task); 开发团队每人主动认领当前开发周期内的task,要求认领的Task不能主要是自己熟悉的部分; 及时同步Task进度到Jira上; 每天下班前站会,总结今天的工作内容,说明明天的工作计划; 当前Sprint完成后,进行总结会议,每人预先准备好总结内容,轮流发言。 实际上类似的流程我们的团队一直在进行。不同的是第5条,对于这种形式我多少持有一些保留态度。 其实第5条这种形式的优势是显而易见的: 能够促进团队成员熟悉所有的产品线; 不会出现一人缺席,一块功能就无人对接的情况; 避免团队成员挑活儿; 团队成员也能在产品、技术等多个层面得到全面的收益。 缺点则相对没那么明显:对于一个产品的每个子工程来说,它的负责人是流动的,换言之就是没有具体的负责人。正常情况下这当然是OK的;出了些问题也没什么大不了,全员一起扛,群策群力也能解决掉。但是一些中间的情况却可能出现问题,影响有这么几个方面: 每个工程有多个人插手,可能会出现整体风格的混乱,也容易出现一些互相拖后腿的情况; 因为不对具体的工程负责,可能就不会深入了解工程的每个细节; 同样因为不对具体工程负责,在需要做一些优化时,也许不会很流畅的进行下去。 举个例子吧:某个团队开发成员在偶然的情况下,发现某个模块需要做些优化,这个优化的效果可能在当下并不明显,不过却需要耗费一定的时间和精力。比较好的情况是,这个人比较有责任感,把这个情况上报了并且能够让团队领导认可这个优化有执行下去的必要性,那么这个优化就有可能被加入到下一次的Sprint中;在下一个Sprint中,负责这个优化的人,碰巧同样认可这个任务,对这个任务的了解也比较深入;那好这个人开始进行工作了,在工作中他发现这个优化需要改动大量的现有代码,比较幸运的是这个工程中的整体风格是一致的,在梳理现有工程上他只需要化费比较少的时间,其他同事也非常配合地帮助他修改各自曾经负责处理过的部分,他的态度也非常的积极,在指定时间内完成了这项任务。这样这次优化算是完美的实现了。 这个例子我写得并不痛快。只是想通过这个例子说明在这种模式下进行开发可能会面临的一些问题,这种模式的展开最需要的就是一个完美的团队:团队成员需要积极负责,团队成员间的沟通成本不能不够低,团队的每个成员对于问题的认可需要保持一致,甚至团队的编码风格等细节也有具体的要求。可想而知,比较困难。
[阅读更多...] -
偶尔三省
最近休假在家,但平时琐事太多,难得有敲代码的时间,不过却是一个反思的好时间。在这里记录一些想法。 不要抱怨 这是一个我不自觉会犯的毛病,以后一定要注意。 抱怨本身只能吐出一下自己的郁闷,不过却不能纾解郁闷,对问题本身也无任何裨益。相反的,每次抱怨只会加重自己的负能量,同时也会对其他人造成一些负面的影响。落到有心人耳里,甚至会造成一些严重的后果。 对于抱怨的事情,首先想的应该是如何解决问题;如果不能解决,则考虑如何将问题抛出;如果不能解决不能抛出,就按常规流程处理好了。 不要厌屋及乌 平时行事多少有些挑剔,连带的,对做事不甚合意的人也有些不是很正面的看法;有时也会因为不喜欢一些人而对他们做的事诸多挑剔。这都是不好的做法。处理事情时只看事情做的怎样,与人相处时只看为人如何,一码归一码。 不要轻易提意见 平时与人相处,对与其相关的事情,如果对方没有刻意征求看法,不要轻易提出自己的意见。 不要做好事 这一点我想了好久。 以前曾看过一个故事,好像是赵威后嫁女相关的。故事内容不大记得了,只有两句话特别有嚼头:“不要做好事”、“好事都不能做,何况是坏事呢”。大致是做好事邀名不可取,做坏事更是不行的道理。 现在想想这两句话觉得应该还有些别的意思:也许做好事的人出发点是好的,但是善意会被人恶意地利用,最后也许会产生坏的结果。 我的想法是不能无偿的做好事,可以为每一分善意设置一个门槛,这样可以过滤掉一些滥用他人善意的行为。 战战兢兢、如履薄冰,生存大致如是。
[阅读更多...] -
设计模式讨论可以休矣
多少有些标题党了。首先声明一下,就我个人来说,我对设计模式没有丝毫反感。我反感的是空泛地没有标的地讨论设计模式,或者说言必谈设计模式。 起因是和同事的一次讨论。讨论的过程不便多说,只说下我的观点:只为学习设计模式而学习设计模式是没有意义的,这样无助于写出好的代码,反而容易写出晦涩的代码。那什么是好的代码呢?在我看来,好的代码起码得有三好:好用、好看、好维护。 好用,指的是写出的代码必须得能满足需求,不然再好的代码都是无意义的代码。 好看,是说代码最少得看起来顺眼,需要遵循普遍约定的格式,类和方法需要有必要的文档(是的我是一名光荣的java程序员),复杂的逻辑处需要有注释。这一点可以参考一些大公司的编码规范,比如Google编码规范或阿里巴巴编码规范(这个真的是良心之作,有详细的pdf文档,还有eclipse和idea插件)。 好维护,这个说起来很容易就话长了。说下我的看法吧:以一个普通的合格的实习生为例,这个实习生理解并做到可以修改你的代码所用的时间,这个时间需要和代码实现的需求的复杂度成正比。注意,这里说和时间成正比的不是代码的复杂度,而是业务需求的复杂度。也许只是写一个“Hello World!”你就用到了十三种设计模式,你的代码精巧无比,但是没有毛用,这个程序本来最多只需要4行代码一分钟的时间就能完成,理解它本应该也不超过一秒钟。当然,能把简单的事情搞复杂也是人才,自然也有他们的用武之地。 我这里说的“三好”代码和设计模式没有必然的关系。有人也许会问:代码不按设计模式来写那按什么来写呢? 我的答案很简单:按需求来写啊。不过在实现需求以后还得多想想你的代码是不是好理解好维护,有冗余的地方就删掉,有复杂的地方就尝试进行简化,简化不了就写上注释,总之尽量把事情搞得简单些,越简单才越见功夫。没看见么,小李飞刀也就那么简简单单的一刀。这样写出代码也许没有遵循任何一种现成的设计模式,但是绝对是最符合需求的模式。 当然,在一开始我就提过了,我并不反感或反对设计模式。我反感的是空谈设计模式,或者将设计模式作为金科玉律。设计模式当前有用,毕竟是前辈们作出的总结,学习一下还是很有必要的。观千剑而后识器,胸中有锦绣才能做出文章。但是将之作为规范就没有必要了。 我见识过一个方法有几百上千行的代码,也见识过因为开发者野心太大而将一个简单需求搞得复杂无比的代码,也见识过为了使用一些新的特性或功能而将整体结构搞得一团糟的代码…林林总总的,大体上都是为了赶上deadline或满足开发者一时的快意而写出的糟糕的代码。对于这些,我只是希望能够在需求没有那么紧张的时候抽时间做些优化,或者在写代码的时候想想以后接收接手你的代码的人是不是会很窝心。 不写了不写了。话早就说尽了,现在已经有些唠叨了。就这样吧。
[阅读更多...] -
关于和leader沟通
处理了一点儿杂事后什么也不想干,干脆写点儿东西好了。 前两天下班后在地铁上和同事聊了些关于和leader沟通的话题。这两天总结了下,一般情况下有如下几个原则: 经常沟通,让leader知道你在做什么; 遇到问题时最好带上自己的解决方案; 挑恰当时间; 尽量周到简洁; 意识到leader更关注结果; 保持一致,避免无意义的冲突。 随时保持沟通不只是可以让leader知道你工作的进度,也可以和他交流工作中遇到问题、解决的方案,让他意识到你对工作的态度和看法,更重要的是可以顺便学习他思考问题的方式、处理问题的手段。哪怕是为了让周报更好写一些,这也是该做的事情。 遇到问题时只是简单的将问题上报给leader并不是一件负责的行为,这在某程度上也可以视为甩锅给他。遇到了问题能先主动解决最好,如果不能解决,负责一些的做法是将自己的思路和方案说出来,这表示:我很重视这个问题,并且愿意承担责任,不过需要多些时间和资源。 第三条没什么好说的,其实不只是和leader,和任何同事交流都需要尊重对方的时间。 沟通工作的事情时应该做到周到简洁清晰,不产生歧义。就事说事,不确定的部分不要说,没弄清楚的老实说不清楚。(这一点我需要注意) 最后两条可以放在一起考虑。leader不太可能事必躬亲,所以他通常只是分配任务制定好目标。我们要做的事情就是和他在目标上保持一致。在实现的过程中可能会出现一些分歧,此时需要提出建议,考虑修正方案,但是目标还是最重要的。在实现目标前,无意义的固执大可以放弃,最愚蠢的就是产生冲突了。 先就这样。 #########
[阅读更多...] -
魔术师or建筑师
前段时间(额,至少是六个月前)接手了一个应用。看了一圈代码心里满是郁闷。应用要处理的事情很简单,但是代码一点儿也不简单。给人的感觉就是为了要使用java8的一个特性而生生将程序扭曲成了一个奇怪的东西。当时就有心吐槽一番,不过拖延症发作才等到了今天。这也是一件好事情,因为在这段时间里多少经过了一些思考和反思——满是负面情绪吐槽只是一时痛快了,思考和反思却是对以后有益的事情。 回到问题上来。可以将一个开发者设计开发应用的心态分成两种:魔术师和建筑师。魔术师是想法最多的那一批人,他们会搬出各种令人眼花缭乱的技术,随口说出各种专业术语,拿出的方案有各种理论的支持。建筑师则相对保守,他们通常是从曾经使用的方案上衍生出方案,没有新意却有经验的支撑。需要在这两者间选择的时候该怎么办呢?可以从三个方面考虑:目标、一致性还有简洁性。 在设计和开发的时候,至少要思量两个目标:怎样完成任务需求以及这个任务对自己有哪些提升?这两个目标一个是对职业的负责、一个是对自己的负责。对职业负责,就是尽量将一切做好,做到问心无愧。对自己负责就是在工作中学习更多的东西、掌握更多的技术、开拓自己的人脉。最好的做法当然是将这两个目标拧到一个方向上。最不好的做法就是一心偷懒敷衍任务。还有一种做法是将任务做成一块试验田,试验田的意思就是更重视过程而不计收成。魔术师最容易犯这个毛病,虽然有时候不是有意的,但是经常会走到为技术而开发的路子上。 在团队开发中需要考虑到一致性。这里的一致性指的是在使用的技术、方案以致编码风格上做到统一。这样做有如下好处:降低风险,减少学习成本和沟通成本。如果不是有明确的需要,就不要打破这种一致性。建筑师很容易加入到一致的队伍中。魔术师则可能会对这种一致性产生反感。 要避免和魔术师的冲突只需要用事实说话。这里有一种思路:列出应用中需要商榷的部分,逐一进行验证,应该保留的就保留,可以简化的就简化、可以删除的就删除。这样最后剩下来的部分就是最该留下来的部分。最后保留的部分也成了一致性的构成。 这里说的魔术师和建筑师的衡量是从技术追求和业务需求两个方向进行的衡量。可能是因为之前想要吐槽的缘故,所以前面多少显得对技术追求型做法有些不认同。不过作为开发就得凭技术说话,对新技术的学习永远也不该停止。但是否要以及怎样将一项技术引入到工作中,就得全面考虑了。 就这样。
[阅读更多...] -
瞻前顾后 – 2016
很早就想对过去一年的工作做个总结,不过懒病发作总不想动手。直到今天科三考试失利,反思了好久才整理好了心情(所以有些时候十分需要当头一盆冷水)。从驾校回来后写了这篇短文来对过去的一年做个总结,并为今年做一些规划。 先说工作吧。过去一年我们主要是在做一款车联网产品,我负责软硬件对接的部分。对我来说,我参与的这个产品是失败了:在我主要参与的一年里,产品正式上线的deadline一拖再拖,拖到后来热情消退,最终走人了事。在离职前后一直在想为什么会走到这一步。现在想想,我们那个产品组的构成很不错:我们软件组的经理是我见过的最负责的经理;硬件组经理在行业里浸润多年,很好地把握了产品的方向;共事的同事在各自的领域也都熟练且专业;公司经理是技术出身,沟通不存在问题。可惜最终的结果让人有些失望:产品始终不能推进市场,在新年开始以后,公司已经开始计划做外包项目收拢资金。至于产品为什么会失败,一开始只是认为对市场反应慢缺少危机感,后来才意识到这只是一个方面,关键仍在开发过程的控制上:阶段性目标不明确,时间线不明确。在产品开发早期,我们也过过一段拼命加班的日子,后来产品大致成形了,推进速度就慢了下来。当时确实是遇到了一些问题——主要是在测试上。因为资源支持不足,测试持续的时间很长(其实资源不该成为问题的,我们的金主就是一家特大的汽车贸易集团)。所谓的测试阶段,就是在公司和同事的几辆车上试用产品,大家在这几辆车的日常使用中一点点发现问题,然后再一点点地调整。时间飞快地过去,从15年10月份开始到16年3月份,我们也适应了慢下来的节奏。如果一开始就明确了产品合格标准以及测试方案,规划好测试调整的时间线,尽力解决资源的问题,完成一轮阶段性目标后再进行迭代,相信起码不会像后来那么被动。至于其他…我也就只能说这些。 再说说关于个人的。在生涯规划方面只有一句话:走了好多弯路,相信辛苦不会白费。其他的方面大致也可以:买了跑步机,每周基本上可以坚持有四五个早上跑1.5到3公里;陪老婆出去转了一圈;在老婆的监督下每天早睡早起;养成了每天读书学习的习惯…. 但是现在这段时间也有了一些不好的习惯:比如拖延症再次频繁发作(写这篇文就用了两天多);每天学习工作前总要刷会儿平板手机;对于技术的执着心有些下降;开始有些浮躁。失利后浮躁的状态稍稍有些冷却,科三虽然没过,但是车考已经不是重心了,需要重新收拾下心情回到正轨上。 在2016年有了新的工作,也开始学车。今年计划的学习方向是计算广告学、算法、java基础、scala,还有英语。因为打算倒空重来,所以干脆删掉了之前全部的文(也没有彻底删掉了,只是备份在其他地方)。在这个博客上以后只会记录一些经过用心整理的相对有价值的的内容,学习的内容会记录在博客园提供的空间上。记录我学习的地址是robin’s note,一个以前使用的博客。 想做的事情很多,学习的事情只能一步步的来,记录下来每一步,除了习惯养成也能起到警醒的作用。同时也希望大家能够监督共勉。 就这样!生活很好,奋斗更好!
[阅读更多...]