锁定老帖子 主题:静态类型语言的优势究竟是什么?
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2006-11-14
robbin 写道 to charon:
ruby on rails根本就没有getter/setter方法,你还有啥好测试的呢? 其实你忽略了一点,当使用类似RoR这样的框架的时候,应用代码量是很少的,所以相应需要测试的部分也很少,比使用静态类型语言需要测试的部分少了很多。 另外,缺少单元测试没有你说的那么恐怖。我们现在就没有写单元测试,ruby代码都已经有6000多行了,编程也好,排错也好,一样很轻松,哪有你吹的那么恐怖。 我在slashdot上类似话题的讨论上曾经看到过有人抱怨动态语言,那个哥们是从事银行系统的,大概有10万行的python代码,最后因为细小隐错不断而觉得无法维护,貌似要转到java平台。(如果把slashdot上近两年来关于ruby和python的帖子和评论看一边,大概还能够找到这个跟贴) 从这哥们的描述来看,他的主要问题是没有单元测试或者单元测试没有达到语句覆盖或者更强的弱条件组合覆盖,从而导致某些非正常流程发生时,流经这些未被测试的语句导致语法错误而最终整个程序都挂掉.对于业务系统来说,这是非常严重的事情。就像我前面说的那样,我自己的程序就曾经不止一次死在logging语句上,因为最初我也不测试这类语句的可通过性。 至于单元测试有没有用,三五人的项目几千行的代码是看不出来的。其实,作坊式开发照样能够做出很多东西来,5年前国内的开发方式基本上是没有单元测试的,照样也能玩得转。 但是,就我自己的体验而言,虽然我并不遵循TDD,但单元测试是足够详尽的,而这个测试网给我的置信度(尤其是在修改代码和较大规模重构时)是之前不可想象的。我估计上千行的程序,就能够在渐增式的单元测试中尝到好处。 不过,这是个哲学问题。 |
|
返回顶楼 | |
发表时间:2006-11-14
我认为分清应用类型是主要的。
传统win32下gui程序的开发,大型系统会用Delphi、VC、VB 但大型web应用肯定是php、java、asp 大型角本?不好意思,这个不知道是什么样子的,unix与linux下成堆成堆的角本都是perl写的,别的语言想抢这个市场也不容易 Ruby的兴起不是因为他是动态语言或什么东西,是因为java下面从structs到spring都没有降低框架的复杂性,所以rails这个框架插在哪儿都会开花 但时间会让java、c#、Python等来削除这些差距 因此:如果ror不能快速壮大,多半也会死在半路上,昙花一现 |
|
返回顶楼 | |
发表时间:2006-11-14
引用 大型角本?不好意思,这个不知道是什么样子的,unix与linux下成堆成堆的角本都是perl写的,别的语言想抢这个市场也不容易
当年C++死守企业应用领域的时候,也是对Java这么说的。 |
|
返回顶楼 | |
发表时间:2006-11-14
引用 大型角本?不好意思,这个不知道是什么样子的,unix与linux下成堆成堆的角本都是perl写的,别的语言想抢这个市场也不容易
当年C++死守企业应用领域的时候,也是对Java这么说的。 |
|
返回顶楼 | |
发表时间:2006-11-14
robbin,你在开发JavaEey时有没有做一些严格的建模工作?比如现在重要的class是不是基本上在设计阶段都考虑到了?还是你认为用RoR就应该遵循RoR提倡的Agile方式进行开发?
|
|
返回顶楼 | |
发表时间:2006-11-14
cookoo 写道 charon 写道 显然,你写的这句反问要表达的意思并不是我的原话的逆否命题。 我的那句话的正确解读应该是: 在静态语言中,某些分支并不需要单元测试 这类地方,只需要语法正确就可以确保没有问题 比如,对于类似前面的那个warning语句,如果是出现在如下场景: if( xxx > 0) logger.warning('...' + x.zzz1() + y.zzz2()) ..... 简单的说,在静态语言中,不论这句程序在哪里,我都不会去测试它。但在动态语言中,我必须保证有一个测试用例流过warning这个语句。 就这个差别。 如果x.zzz1()和y.zzz2()可能会抛出exception呢? 从我举的这个例子当中,logging这类的操作本身就应当是没有副作用的,所以也不会去调用那些会产生副作用的函数和方法。 退一步讲,如果这类应当没有副作用的操作里面干了有副作用的这些事情而且抛出异常,实际上,程序本身在之前就已经处于不正常状态了,让logging这类操作来捕获或反映这个状态,显然是不合适的。 |
|
返回顶楼 | |
发表时间:2006-11-14
robbin 写道 to charon:
ruby on rails根本就没有getter/setter方法,你还有啥好测试的呢? 关于getter/setter类方法的测试,其实有两个意思。 一个是定义方的测试,只有强迫症才会在定义方测试。 另一个是调用方的测试,java中getter/setter只是属性访问方式的封装,在调用这类方法时,写完了通过编译就算ok了。 而在动态语言中,对属性访问的语句都必须用测试流一边。最大的好处是消除笔误和未赋值访问. |
|
返回顶楼 | |
发表时间:2006-11-14
动态语言缺乏编译检查,的确是一个问题,不过我觉得这个问题并不像上面说的那么严重。比起其他类型的错误如逻辑错误、设计错误、并发错误,语法错误实在是太容易检查和排除了,通常只要发生过一次,几分钟就可以定位并消除,比其他类型的错误动辄要几小时甚至几天来debug,根本不可同日而语。
我在开始写脚本的头一个星期,三天两头出现语法错误,导致程序崩溃,一个月以后基本上就没有了。就是出现错误,也很快就能发现。现在的脚本编辑器如pythonwin和kodomo已经能够显示语法提示,要写出没有或者很少语法错误的脚本,比过去已经容易多了。 要保证整个程序不会挂掉也容易,在高层模块加一个try/catch就够了,至少你的程序不会因此垮掉。 编译检查虽然好,但是它的局限也是很明显的,只要涉及任何动态特征——强制类型转换、动态代理、反射....它很快就起不上作用了。像Hibernate或者Spring这类高度依赖配置的框架,如果你在xml里敲错了一个字母,编译器检查又能帮什么忙呢? |
|
返回顶楼 | |
发表时间:2006-11-14
引用 robbin 写道 to charon: ruby on rails根本就没有getter/setter方法,你还有啥好测试的呢? 关于getter/setter类方法的测试,其实有两个意思。 一个是定义方的测试,只有强迫症才会在定义方测试。 另一个是调用方的测试,java中getter/setter只是属性访问方式的封装,在调用这类方法时,写完了通过编译就算ok了。 而在动态语言中,对属性访问的语句都必须用测试流一边。最大的好处是消除笔误和未赋值访问. 单元测试覆盖到这些语句很难么?实践中遵循TDD,就会在不知不觉中覆盖到所有代码。我根本感觉不到额外的成本。 再说逃离单元测试的覆盖值得那么沾沾自喜么?logger为null是编译器能检查出来的? 另外,无论是编译器还是单元测试都不能保证代码正确无误--世界上没有任何方法或者技术可以做到! 但是单元测试给我们创造最多的机会来发现错误,而TDD给我们更多利用单元测试的机会。 |
|
返回顶楼 | |
发表时间:2006-11-14
那只剩下一个区别了:c/c++可以访问底层,效率也高很多!java/c# 之流完全就淘汰了!
|
|
返回顶楼 | |