思维导图
介绍
叫老大不光是因为职位比我高,还因为技术也让人佩服!
今天跟老大聊聊我们一些代码结构的问题,有些可能会对你是有帮助的。如果大家有不同的看法,可以提出来,一起讨论一下。
对话
1>单个文件巨大(超过5000行)
我:文件大会不会影响性能啊?PHP语言在处理源文件的时候(这个主要是php的词法分析和语法分析),会将源文件切分为一个一个的标记(token)。如果文件很大的话,把我们当前不需要的方法都会做标记的,这样不是明显影响性能吗?
老大:这个在性能方面的影响是比较小的。我们在考虑性能的时候,要考虑全局观,比如展示页面的时候,打开页面很慢,那我们首先考虑的就不是文件大小的问题,而是每个模块的加载速度。比如,通过你的断点设置,你发现某个产品列表的读取是比较慢的,那就要考虑,是不是组装数据慢了,还是从接口(数据库或者中间层)读数据慢了?如果是组装数据慢了,那就要重构这个算法,或者跟产品人员商量能否修改方案。如果是接口读取数据慢了,那是不是需要加机器或者加索引来解决问题。——所以,考虑性能问题,不能抓住小问题,要考虑的是最影响性能的地方进行修改。
我:那如果切分大文件类到不同的类有什么不好吗?
老大:如果在一个方法体中,你通过很多的require_once添加很多的类文件,那么不也是影响性能吗?——require_once本身也耗费性能!
给我画了一张图(类似于上面的图):
我:那我可以用include,逻辑加载文件,按条件加载文件。这样就能减少加载文件的数目!
老大:那么你怎么按照条件加载?
我:比如,我可以按照分类去加载文件,电影的时候,我就把电影相关的程序文件加载进来,电视的时候就把电视相关的程序文件加载进来。
老大:那将来电视要用到电影里的内容的时候,你怎么办?或者很多分类用到你电影分类里的内容的时候你怎么办?
我:那我就放置一堆的"||"代码(如if('电影' === $category || '电视' === $category || '音乐' === $category){})。 后来我琢磨了一下,确实是,这样做的话,一个方法里会有很多这种if语句,那我要对应某一个分类内容的时候,我就要看一堆的if了。还真不如写在一块呢或者重构代码了!
2>autoload()方法。
类似下面的代码。
<?php Test::getName(); function __autoload($className){ echo $className,"\n";exit(); }
运行结果:
我们都知道__autoload()方法性能并不是很好,一般不鼓励去使用这个方法。所以,我在调用类的时候,我就加了这么一句:
对话:
我:我觉得__autoload方法性能不是很好,所以我在调用别的模块的时候,我就用了include方法。
老大:你这样做,一是整个代码看起来没那么规范,二是,如果将来要修改框架了,我们就要查看所有的这样的代码文件,因为比如,你的入口文件移动到别的文件夹下面,那么你的Test.class.php文件在什么位置,你知道吗?
如果我们调用__autoload()方法,我们只需要修改这个接口就可以了,因为所有的类调用都经过了这个方法,这样比较好管理。
3> 一个方法尽量保持在一个屏幕内,一行不超过80个字符。
我:我觉得我们的类里面的方法太长了,很多都超过几个屏幕,才能把当前的方法看完。我个人比较推崇"尽量把方法放在一个屏幕内"和"让一个方法做一件事"。有的时候看到一个很长的方法的时候头大了!
老大:
一个方法就是做一件事啊,比如test()方法,就做test()。以前php没有面向对象的时候,我们经常不是把代码都写在一个文件里吗?
我们不应该“为了拆方法,而把方法硬性拆分。而应该是因为业务需要而对方法拆分!”。而且函数调用我们知道,本身也是耗费性能和内存的。如果你这个方法体内的有些部分,其他方法也要调用,那么这时候你可以把这部分代码做成一个方法。
如果你的方法里有很多调用其他类里的方法,不也看着很麻烦吗?还不如写到一个方法里呢!这样还比较直观些。
4> 找回以前删除的代码。
我:如果某个功能产品要求撤下来,但是过了很长一段时间,产品又要求再上这个功能。那么我原来的代码是删除呢?还是只做注释呢!
老大:删除掉!
我:那我怎么恢复呢?要把原来代码做备份吗?
老大:你可以使用版本管理软件做恢复。如svn。
例子演示:
(1)最初代码
svn提交代码:
(2)产品要求下线代码
svn提交代码:
(3)隔了一段时间,产品又要求重新上线该模块。
svn操作:先查询日志,然后针对日志进行合并
总结
上面的问题,我估计你也遇到过,所以大家共勉下吧!
题外话:曾经我在离开一家工作一年的公司的时候!项目经理就跟我说你如果频繁跳槽,会对你的将来的发展是不利的,但是没有告诉我怎么不利?现在我有点明白了,因为我到过的公司很多技术过硬的人,都是在这个公司带过3年以上的人。我发现如果你在一家公司待很长时间,对你的技术提升是很有帮助的。
1》 不停的重构代码,提升你的代码质量。
我们开始进入公司的时候,一般都是公司急需赶个项目人手缺乏。等项目完成,一般都是1年左右。如果你在公司待足够长的时间,这个项目多多少少会跟你扯上边的,这时候,你会不停的翻看自己的代码,你也会不断的调整代码, 不断的重构你的代码——跟写文章一眼,你不停的看自己写过的文章,你会不停的做修改,越修改你的文章会越让你喜欢。
2》业务熟悉,能够更快更好的写出代码!——我个人比较喜欢“行云流水”似的感觉。
你如果在一个公司待了很长一段时间,那么你对这个领域是非常熟悉的。新需求上来,你会很快的知道怎么做代码架构,比如上面提到的,你就知道方法中,哪些代码部分可以抽出来,独立做成一个方法;你也会知道,将来什么地方会频繁修改的。——写代码,如行云流水般!
网友对话
跟大家交流收获很多,也感谢大家多提意见,我们共同探讨。
youxiachai:不用注释来注释那些可能有用的代码.....最近,看代码整洁之道,也提到了一样的问题?
我:这书我也看过,跟以前同事聊过,但是他们都比较推崇尽量写注释。我也懒得写注释————呵呵。 如果我们的代码规范大家都比较认可的话,那么我们可以省略掉很多注释。 如:listVideo我们都知道这是获取视频列表的。
——————后来我发现,我看的是《代码大全》,误会了!
msnweb:都是挺初级的问题, 有一点 不同意 require_once 影响性能。.... 和db socket io 这种性能影响根本不用考虑。
还有一点 就是单元测试。 这对你的水平提高会很大。
还有一点 就是单元测试。 这对你的水平提高会很大。
我:对,我这个都是初级的问题,但是很多初级的问题,往往是我们工作很多年都容易忽略的地方。有的时候,看代码的时候老是觉得不舒服,但是说不出来,哪里不舒服。
我:单元测试我这里是比较头疼的问题,因为现在的代码框架已经有很多年历史了,里面有很多的比如rewrite,alias,甚至还有把变量放到apache的配置文件的,然后通过php去读取。
我:单元测试我这里是比较头疼的问题,因为现在的代码框架已经有很多年历史了,里面有很多的比如rewrite,alias,甚至还有把变量放到apache的配置文件的,然后通过php去读取。
maxspeed40k:autoload影响性能是网络上最大的谬论之一。
多个小文件块还是单个大文件块,可以在没有opcode缓存和有opcode缓存下做个性能测试,你会发现不一样的答案,另外,单个大文件同时编辑方便吗?加载以及依赖的问题是用autoload不正好是解决这个问题的?
多个小文件块还是单个大文件块,可以在没有opcode缓存和有opcode缓存下做个性能测试,你会发现不一样的答案,另外,单个大文件同时编辑方便吗?加载以及依赖的问题是用autoload不正好是解决这个问题的?
我:这个真没做过实验,哪天时间允许,我做个实验试试。
maxspeed40k:一 行80个字符少了一点,以前代码要打印,打印机质量不高,所以限制为80,现在完全可以达到120。一个方法的代码如果超过一屏幕,是应该考虑重构,如何 写得更加简洁,将一些代码东西提炼出提高复用,通过方法名让代码更容易立即,更多好处可以参考《代码大全》相关章节,有非常好的介绍。我们看下 cake,yii,discuz...
我:同意他的观点。
如果方法中的代码很多没有复用价值,你还重构吗?我一般的做法是把那些经常需要变化的和其他方法调用的公共代码剥离出来做成一个方法。
如果方法中的代码很多没有复用价值,你还重构吗?我一般的做法是把那些经常需要变化的和其他方法调用的公共代码剥离出来做成一个方法。
大家还有什么宝贵意见都可以进行交流。
喜欢编程