好的代码应该是语义化的、自解释的,配合文档注释和单元测试,甚至可以说代码本身就是文档。说真心话,thinkphp的源代码根本没心情读下去,我猜凡是读过symfony、laravel、phalcon等流行源代码的应该都没心情去读thinkphp。
我觉得thinkphp在国内的流行是一个错误,这误导了很多人,为了写这个评论,我忍受痛苦git clonehttps://github.com/liu21st/thinkphp.git 翻开源代码一点点表达下自己的感受。

首先index.php入口文件,判断php版本小于5.3就die是很不友好的,这干扰了自动化测试流程,正确的做法应该是用抛出异常,把选择交给应用层,而不是强制退出。第二,尽量不要define,要尽可能的少用,这些全是隐规则,应该越少越好,而且这此东西是全局的,很难保证不与其它组件冲突。同样的道理ThinkPHP/ThinkPHP.php文件里大量的define定义了大量的隐规则,对开发者不友好。

ThinkPHP/Common/functions.php定义大量的全局函数,这是很变态的做法,极易被滥用,加重耦合度,代码不应该追求少写字符,而应该追求易于直观理解,易于维护,少写那么几个字符看起来好象是节省了写代码的时间,但是一个项目很可能要不同的人长期维护的,增加阅读代码的理解成本是可恶的做法,而且现代IDE都支持自动补全,简写更没意义,纯粹浪费代码评审者和后期维护者的时间。

ThinkPHP/Conf/convention.php debug.php定义了大量的应用层的东西,这些东西不应该由框架决定而应该交给应用层,defined('THINK_PATH') or exit();也是不对的,框架里不应该出现exit() die这些东西,这太暴力了,应该抛出异常,由应用层捕获决定如何处理。

ThinkPHP/Library/Behavior/*.class.php 首先.class.php扩展名就很奇葩,fig标准存在的情况下,大家应该共同去推动一个标准的发展,而不是范NIH综合症,代码里依赖自定义的全局函数也就算了,居然也依赖$_SERVER全局函数,你怎么知道用户不会在cli模式下使用框架呢?

再以ThinkPHP/Library/Think/Cache.class.php来说,这个cache类设计很业余,低层的Cache/Driver居然没有定义接口,而实际上里面的代码大部分是按照get(),set(),rm(),clear()规范实现的,这相当于又出现了一个隐规则,关键少部分不是按这个规范实现的。根本没必要cache类本身实现单例的,更好的解决方案是有个容器负责单例或多例。

我觉得ThinkPHP越繁荣,对PHP开发者的成长伤害越大。Yii早期版本看过,当时觉得耦合度太高,不适合搞长期维护型项目。也不建议学习。象phalcon这种各个组件都是可以单独拿出来用的,相互之间是松散组合,极少隐规则,不限制开发者,开发者可以自由组合项目结构。

最后我没有发现ThinkPHP有任何单元测试的代码,搞不懂质量如何保证。

我希望大家能容忍我讲真心话,不管我说的错也好,对也好,不要觉得不开心,感情用事随便扣分就好。

thinkphp的缺点,好的代码应该是什么样的
标签: