论坛首页 Java企业应用论坛

敲响OO时代的丧钟!——DJ对于数据持久化的支持(3)

浏览 192832 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2005-07-10  
<回ajoo>:
好的,那我们就来把细节一点点挖个清楚,真理越辨越明,哪怕我说的都是错的,我也希望我的辩论能给大家有所启发,这就够了。
引用

这话好像和我说的对不上茬。
我是说模板作为产生程序的程序,本身没有静态类型检查(就是在它产生并且准备产生目标源代码之前的检查)。至于它产生的代码是否是静态类型的,这是另一回事,不要把两者混淆了。

模板程序本身的bug最难查,基本上就得靠干猜,死读代码。
另外,越界检查,异常系统,保证了在java里面即使不用范型,查找错误的代价也被降了下来。不是什么相提并论的意思。


这个地方是你把两者关联起来,我的意思是(大部分的)模板通过间接的(类型等)检查,也同样保证代码的静态安全。我的本意就是要指出不要过于夸大静态类型检查的作用。

模板程序本身的bug难查,我不知道你说的是什么意思,是自己写的模板程序的错误,还是引用别人的模板内部的错误,前者据我所知,在运行和普通的代码几乎没有区别,而且往往模板代码都比较短小精悍,根本没法给庞大程序本身造成什么负担。当然你如果是做库,为得不到一个通用而且足够鲁棒的结果而恼火,呵呵,这个我也不知道该怪谁,反正喜欢怎么着就怎么着吧。要如果是引用别人代码有问题,呵呵,这个问题就有的讨论了。

我也有在编译错误发生的时候去读代码的时候,尽管很少。但这也没什么,藉我一人之力和寥寥无几的范例,有这样的时候不足为奇。如果在我周围有和用spring一样多的人,我相信这根本不是问题。运行期我还是要说,没有必要。

还有下面的运行期保证,用模板并不代表就不需要或者避免它,这早已是c++程序中的普遍特性。而且这个谁也保证不了,java的运行系统也一样。我的意思是静态检查只会强于它。

引用

你所知不见得就是事实。这个争辩没什么意义。

我只是介绍我的经验,当然因为某些原因,我不一定影响的了谁,但说一下也无妨吧。没有根据的争辩才是没有意义的。

引用

你不过是把“合格程序员”的标准提高到可以猜测模板的古怪的错误信息的程度而已。概念游戏。

呵呵,你误解我的意思间接误导大家,这是我一定要反驳的。稍微理解一些的人就会知道我说的绝对不是这个意思。我是说如果出错了,肯定是你的代码有问题,而没必要去追究那些提示信息本身。如果谁觉得使用一个接口报告的错误都看不出代码有什么问题,我只能说他学艺不精。退一步讲,就算是库的问题,在你无法发现的情况下,放弃也不算是什么天大的事吧。在abp好像我也不止一次措词强烈,这一点elm大人应该有所赞同。

引用

如此说来,拿汇编写的库也可以这么说:我保证我的程序正确,你不用跟进我的代码。也别管我花了多少年来调试我这个完美无瑕的库。
这只能证明作为黑盒使用的库的作用,不能用来表示写这个库的那个语言有什么好的。

呵呵,你这么说我也没有什么意见,只使用库而不关心库本来就是大多数情况。这没什么可以炫耀的,我并没有跟语言挂上钩,我关心的只是这样的库能不能给我带来足够的好处。

引用

c++er总喜欢把“库”神化。殊不知库也是程序,完全没有必要在库和使用代码间划一个鸿沟,除非你们只认可那么寥寥几个权威的库,stl, boost。看看java世界,任何人都可以写自己的open source库,项目也可以做自己的公有工具库。这才是一个好用的工具该有的样子。而不是一个“库”这么屁大点的事都要劳烦天才级别的模板发烧友。


我不知道你的结论是怎么得出的,反正我是不知道有这样的事情。在c++里,也一样可以提供很多的库,这跟其他语言都一样,这个方面我们没有必要去划出什么语言界限来。java库的繁荣,根本原因在于它有一个统一的标准。我也希望看到c++有通用库可以使用,好不容易有“天才们”提供象boost这样的东西帮你弥合各种差距,还有方便的功能,怎么就被你说的这么不值?

引用

何况,你没有需要跟踪到模板库内部,也许只是你足够幸运,或者足够合格。那么多不幸的“非合格的程序员”怎么办?
你不承认或者不愿意承认模板程序中的多如牛毛的陷阱,我也没办法,全靠个人经验说话,也说不到一块儿去。

这不是承认不承认的事情,该承认的我都会承认,比如elm大人说的部分缺点。但如你这么夸张的批判,而且没什么具体根据的,我当然会根据自己的经验反驳。

引用

通过增加一个本身无法调试,错误信息古怪的复杂的中间层来得到那么一点点“简单性”?我的意思直白的很:得不偿失。

呵呵,我不知道你根据什么来说有古怪的错误信息,还是那句话,Typelist本身很稳定,引用起来也很简单,可以帮助你把变化集中起来,保证你的设计的正确性。而且代码也一样可以调试的,这一点根本没有任何区别。
好的,这里我就不写代码了,在我想介绍的文章中,第一个就会用到这个。

引用

别老在这误导无辜的java程序员,整数参数那东西都不能是变量,随便一个f[i]就绕过了你的编译期检查,java程序员看不上眼的。

不是变量怎么了,难道代码里都是变量?不是变量更加确定,稳定,更少可能的发生错误。难道你那个f[i]凭空跳出来的,我还真没想到你会这么说。需要强调设计的时候强调设计,谈到具体代码似乎就把设计抛到一边(上边的Typelist也类似)。就算如你所说,运行期检查也是很容易的,一句话解决:
assert(i < N);;

还有我对于提到java程序员,有意识的划分界限也有意见,我也用java,我想在这里的人是为了解决问题而聚到一起,可能有OO等崇拜,但大部分人应该没有语言情节。
0 请登录后投票
   发表时间:2005-07-10  
tiger,
我也不想搞语言之争。不过是你在这提出模板来的。魔板只是c++才有,所以似乎语言上的争论不可避免。


其实,我说的就是:模板编程不是解决开发问题的良方。

这包括两个方面:
1。自己写模板库。对这点你似乎也同意它的代价很大?如此,我们就不争论了。

2。调用现成模板库。
对这个,你认为象typelist这种用用很简单,不会出错。我不敢苟同。
一般来说,魔板程序不是完美的黑盒,它没有象函数接口签名检查这种东西,虽然最终的c++代码是静态类型,并且可以调试跟踪。但是meta-code也是程序!它负责声称目标c++代码。这个程序却不能调试跟踪。

实际中,魔板程序的使用并非那么简明,没有一定的语言上的功底上来就用模板库会死的很难看。你所说的看到调用错误能够分析出来自己哪里用错了,这绝对不是普通程序员普遍做得到的。
这在普通c++程序或者java来说就不是这种情况,随便一个一般人都可以用调用一个函数或者类。调用出错,编译器会给出最明确简单的错误信息。


综上所述,模板写起来很难,源代码读起来很难。一旦除了bug,想要确定不是库德问题也很难。毕竟,一个语言如果难写,那么写出来的库的出bug的概率也会大得多。这大概也是为什么c++的模板库不象其他语言的库那样雨后春笋,到处都是的原因。

用起来也没有普通函数那么简单,再加上维护,编译器兼容等等问题,可以说一定要谨慎使用。


关于那个常量参数,我一直强调的一点:模板库在常量和变量之间划了一条不可逾越的鸿沟。
如果你用模板写了一段逻辑,它使用编译期常量,那么,如果什么时候你发现这个逻辑可以用在运行时的变量的时候,没办法,只能把同样的逻辑用普通的c++重写。(就拿那个meta-program里面著名的factorial的例子来说)
所以,编译时整数不是什么值得炫耀的东西,即使不能算垃圾的话。
我还真没想到你把它还当个宝。
0 请登录后投票
   发表时间:2005-07-10  
ajoo:
虽然你说的肯定有值得重视的地方,比如我也不觉得过分在模板上炫耀技巧以及强调细节的技巧是多么有价值的,所以我很少拿代码去说话,除非这样的代码非常有代表性(不好意思,这和这里很多人有些背道而驰,也许是我自身比较懒),再比如Andrei的很多注重细节的讲解我也很不以为然。但是我也要强调,争论问题不是模棱两可,也不能仅仅片面的看待问题。

模板本身如何,这本来就是值得研究的问题,我讨论的伊始就说过了。其也是经历了发展了,我想模板提出者肯定没想到模板在本身没有什么大的变化发展到了今天是这样的。基本上模板提出的伊始也不过是在之前某些语言特性上的一个扩充和通用的实现机制,也就是泛型。

模板写起来很难,这也要相对的来看,比如做个容器什么的,或者偶尔适应一下局部变化,而显然没必要重写代码的情况下,我觉得没什么难的,调试起来也没有负担,反而更加一致,减少人为错误发生的可能。

我说的分析错误你还是误解的,我的意思是一些语法逻辑上的问题,一般在有明确接口情况下,如果你有着基本语言的基础,分析它应该不是负担。当然现实中不合格的人比比皆是,但这样的人你让他去用什么spring或者这个库那个库,问题同样是一大堆。

我也没拿什么当作宝,我也从不认为自己有什么宝贝可以视人。我所说的都是一些基本的东西,至于你认为它有多大的用要视具体情况来看。比如关于编译期整数Andrei的Int2Type就比你说的factorial有价值,在实际中,boost::bind就可能定比traits更“有用”。

还是那句话,能解决问题的就是宝,不能的话,再炫目的技巧也是白搭。
0 请登录后投票
   发表时间:2005-07-10  
firebody 写道
庄表伟 写道
firebody 写道
我想,在如今,这个好坏的标准还是根据重复代码的多少来的最直接。
虽然,有时候重复代码在目前或者可以容忍的将来是允许存在的,但是如果他的频率出现的足够多,甚至我们可以预见这种重复代码的出现将会在以后不断的出现时,这意味着现有的代码是不好的。需要做一个重构! 小范围或者小规模的重构如果可以解决问题自然是好事,然而当自己绞尽脑计也无法整理出一个好的设计来消除这种重复的代码,有人会怀疑所谓OO设计标准的必要性! 这确实是一个很打击人的事情,如果系统庞大到了一种地步,一开始不好的设计,到后来,发现OO还不如比直接过程式 编程来得直接,然后就把大量的逻辑用if else封装在某个对象中,这样一来,系统居然也可以正常工作。 除了那似乎虚无缥缈的扩展,一切都很美好!
虽然这是可以工作的东西,但是谁都不敢保证看到里面的代码很舒心,也不敢保证一个扩展会带来多少工作量!
诚然,在比较复杂的系统荣,好的OO设计非常困难,甚至难以实现。 但是,有一点,无论如何都应该明确,如果注重及时重构,注重消除重复代码这个标准,那么好的设计总归会逐渐浮现出来,整个过程将会循序渐进的进行下去,系统地结构也会越来越好。但是如果不考虑这些,或者源于多种原因而无法改进设计(比如无法设计出一个更好的方案或者项目周期压力等等!!),那么问题的积累是非常可怕的,OO的开发最终也会下降到一个用伪 OO的方式来进行过程式编程的开发,只不过这里的类似C语言的函数用一个个好看的对象封装罢了。
设计是一个循序渐进而曲折的过程,只要不断而及时的改进,OO才会越来越美好,否则,正如很多人说的,还是直接过程编程来的方便。 不是吗?


呵呵,最少重复代码不适用于“面向接口编程”的。你应该也看到过一个Interface加一个Impl的设计,号称是“接口编程”吧。

我不知道你所理解的面向接口编程是什么?
我不认为面向接口编程和减少重复代码之间有何必要的联系! 一个Interface+ impl 有时候是所谓浅薄理解面向接口编程的产物,有时候是设计模式的产物,有时候是一种语言规范的方式,或者一种技术得以体现的规定等等。
我不知道代码重复与这个Interface+impl 之间有何关系。
如果硬要指责Interface+impl有什么诟病的话,不如说它是过渡面向接口编程的产物吧!


我想说的意思是,消除重复代码,不一定就是OO设计的最高目标,根据“可复用的设计”这一目标,实现同样的需求,代码更多也是可能的。

过度设计,也就是“过度可复用”罢了。既然追求的就是可复用,追求得过了一点,为什么就是错的,这一点,“GoF”可没有告诉我们。
0 请登录后投票
   发表时间:2005-07-11  
最初我知道的OO是这样产生的:随着计算机的发展,程序越来越庞大,庞大到了难以理解的地步,作为计算机语言天生和人类语言有着巨大的鸿沟,为了更好的描述程序逻辑于是产生了OO,使得计算机语言可以以OO的方式更逼近自然语言,使得程序更容易理解。其他代码减少等只是这一目的的附带效果。如果说到要敲响这个OO时代的钟声,那么第5代语言的前奏在哪里呢?
0 请登录后投票
   发表时间:2005-07-11  
wolfsquare 写道
最初我知道的OO是这样产生的:随着计算机的发展,程序越来越庞大,庞大到了难以理解的地步,作为计算机语言天生和人类语言有着巨大的鸿沟,为了更好的描述程序逻辑于是产生了OO,使得计算机语言可以以OO的方式更逼近自然语言,使得程序更容易理解。其他代码减少等只是这一目的的附带效果。如果说到要敲响这个OO时代的钟声,那么第5代语言的前奏在哪里呢?

为什么“更好的描述程序逻辑”就一定需要OO?
(map square sequence)

这不也很能描述程序逻辑吗?
0 请登录后投票
   发表时间:2005-07-11  
TiGEr.zZ 写道
ajoo:
虽然你说的肯定有值得重视的地方,比如我也不觉得过分在模板上炫耀技巧以及强调细节的技巧是多么有价值的,所以我很少拿代码去说话,除非这样的代码非常有代表性(不好意思,这和这里很多人有些背道而驰,也许是我自身比较懒),再比如Andrei的很多注重细节的讲解我也很不以为然。但是我也要强调,争论问题不是模棱两可,也不能仅仅片面的看待问题。

模板本身如何,这本来就是值得研究的问题,我讨论的伊始就说过了。其也是经历了发展了,我想模板提出者肯定没想到模板在本身没有什么大的变化发展到了今天是这样的。基本上模板提出的伊始也不过是在之前某些语言特性上的一个扩充和通用的实现机制,也就是泛型。

模板写起来很难,这也要相对的来看,比如做个容器什么的,或者偶尔适应一下局部变化,而显然没必要重写代码的情况下,我觉得没什么难的,调试起来也没有负担,反而更加一致,减少人为错误发生的可能。

我说的分析错误你还是误解的,我的意思是一些语法逻辑上的问题,一般在有明确接口情况下,如果你有着基本语言的基础,分析它应该不是负担。当然现实中不合格的人比比皆是,但这样的人你让他去用什么spring或者这个库那个库,问题同样是一大堆。

我也没拿什么当作宝,我也从不认为自己有什么宝贝可以视人。我所说的都是一些基本的东西,至于你认为它有多大的用要视具体情况来看。比如关于编译期整数Andrei的Int2Type就比你说的factorial有价值,在实际中,boost::bind就可能定比traits更“有用”。

还是那句话,能解决问题的就是宝,不能的话,再炫目的技巧也是白搭。


你在人家 java 的地头宣传 C++ 的好处 …… 是不是存心来砸场子的呀? 
0 请登录后投票
   发表时间:2005-07-11  
gigix 写道
(map square sequence)

这不也很能描述程序逻辑吗?

很抱歉,我没能看明白你代码的意思
gigix 写道
为什么“更好的描述程序逻辑”就一定需要OO?

那为什么C,C++之类的高级语言替代了汇编或者机器码编程?
0 请登录后投票
   发表时间:2005-07-11  
wolfsquare 写道
gigix 写道
(map square sequence)

这不也很能描述程序逻辑吗?

很抱歉,我没能看明白你代码的意思
gigix 写道
为什么“更好的描述程序逻辑”就一定需要OO?

那为什么C,C++之类的高级语言替代了汇编或者机器码编程?

map是这样的一个操作:(map proc list),将一个操作(即proc)作用于一个列表(即list)的每个元素,得到的结果是另一个列表,其元素个数与被处理列表相等。例如有这么一个列表:
(define seq '(1 2 3 4 5))

我希望对列表中的每个元素做平方运算,就这样写:
(map square seq)

得到结果就是(1 4 9 16 25)。其中的square定义是:
(define (square x) (* x x))

这不是很好的抽象么,把“列表之间的映射”这件事情描述得很清楚,而且没有对象。不管square还是seq,这两个元素都没有为对方做任何预先的准备,就可以把它们拉到一起来用。
0 请登录后投票
   发表时间:2005-07-11  
wolfsquare 写道
最初我知道的OO是这样产生的:随着计算机的发展,程序越来越庞大,庞大到了难以理解的地步,作为计算机语言天生和人类语言有着巨大的鸿沟,为了更好的描述程序逻辑于是产生了OO,使得计算机语言可以以OO的方式更逼近自然语言,使得程序更容易理解。其他代码减少等只是这一目的的附带效果。如果说到要敲响这个OO时代的钟声,那么第5代语言的前奏在哪里呢?


OO的产生应该不是为了更好的描述程序逻辑,其他专门语言会更出色,OO应该是为了更好的描述程序结构而生,试图以人类容易理解的一般习惯性方式来表述复杂系统。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics