怪怪 | Nothing, Everything

"有过一个发疯的时刻,有感觉的钢琴以为它是世界上仅有的一架钢琴,宇宙的全部和谐都发生在它身上." - 狄德罗
随笔 - 83, 文章 - 2, 评论 - 1656, 引用 - 38
数据加载中……

Knuth访谈: 老将出马, 一个顶俩

大家追潮流追的也不少了, 也看看比大牛还大牛好几倍的家伙怎么说; 听见些不同的声音, 总比铺天盖地全是流行歌曲, 要强一些; 别搞得好像一些明星加商业宣传, 就代表了真正的计算机科学家的看法和发展趋势似的。 其实很多时候, 我们认为的大势, 总是那几个人或几个团体再表演罢了; 我真正担心的, 是在那些似是而非的学问上花费过多的精力, 最后才发现都是一场空。

如果不知道D.E.Knuth是谁, 可以自己Baidu/Google/Yahoo/Live(排名不分先后)一下。 原文很长, 截取并胡乱翻译了三段, 关于单元测试 、 极限编程两个时髦东西的, 和关于可重用代码这一面向对象一直所关心的主题的。 这老人家也只是发表一下看法, 并没有说为什么, 但是呢, 我觉得可以当一个警钟敲了一下, 有没有道理的, 权当一个提醒, 一个敦促自己思考的契机吧。

另外, 那些对流行不感冒的兄弟, 也不用觉得自己太落后了, 至少肯定比明星梯队权威的人和你一样土; 问题的关键是写出像样的软件, 不是么? 闲话不多说了, 原文: http://www.informit.com/articles/article.aspx?p=1193856

关于单元测试

the idea of immediate compilation and "unit tests" appeals to me only rarely, when I’m feeling my way in a totally unknown environment and need feedback about what works and what doesn’t. Otherwise, lots of time is wasted on activities that I simply never need to perform or even think about. Nothing needs to be "mocked up."

及时编译和"unit tests"的主意对我来说只用在很少的情况, 比如当我完全不熟悉环境, 需要搞清楚啥能转啥不能转的时候。 另外, 在好多根本不需要干甚至根本无需了解的事情上, 会浪费大量的时间。没啥是需要被"mocked up"地~~

关于极限编程

I hate to duck your questions even though I also hate to offend other people’s sensibilities—given that software methodology has always been akin to religion. With the caveat that there’s no reason anybody should care about the opinions of a computer scientist/mathematician like me regarding software development, let me just say that almost everything I’ve ever heard associated with the term "extreme programming" sounds like exactly the wrong way to go...with one exception. The exception is the idea of working in teams and reading each other’s code. That idea is crucial, and it might even mask out all the terrible aspects of extreme programming that alarm me.

虽然我更讨厌让他人的敏感神经感到不快, 不过我也不喜欢回避问题——扔出那些软件方法论经常搞得跟宗教信仰似的。 我首先我提出一个警告, 任何人没有理由关心一个像我这样(权威或者牛B, 凡是括号里是翻译者自己加的)的计算机科学家或数学家如何看待软件开发; 然后咱们来说说这事: 几乎我听见的每一件和极限编程相关的事情, 都肯定的走在了错误的小路上, 除了一个例外。 这个例外是在团队中工作, 并且互相读代码的主意。 这个主意很关键, 以至于它(的优点)能够掩盖所有那些极限编程中让我警惕的恐怖方面。

关于可重用代码

I also must confess to a strong bias against the fashion for reusable code. To me, "re-editable code" is much, much better than an untouchable black box or toolkit. I could go on and on about this. If you’re totally convinced that reusable code is wonderful, I probably won’t be able to sway you anyway, but you’ll never convince me that reusable code isn’t mostly a menace.

我也必须坦白对可重用代码, 我有很强烈的偏见。 对我来说, 可更改的代码代表了更多的东西, 而且比一个不能深入的黑箱或者工具箱要好得多。 我可以继续下去。 如果你仍然信服可重用代码很棒, 我也不见得抓着你的脑袋使劲儿晃(让你清醒), 不过你也甭想让我相信可重用代码不是一个很不咋地的东西。 (在这里, 可重用代码, 应该代表的是编译之后的成果; 那些可以拿到源代码, 并可以自己改的, 属于可更改的代码,在这篇文章前面, 高老爷子对开源还是很看好地)

关于并行编程高老爷子也有些不一样的见解, 太长了, 就不原文贴出了。 不得不说虽然他年纪大了, 一些话还是有启发性的。  嗯不过这些话如果换我说, 估计就成骂街了。 真是老将出马, 一个顶俩。 不过也许有人要问, "廉颇老矣, 尚能饭否"了吧?

翻译的比较草, 有啥问题就留言, 不过我暂时不参与对错的讨论了。 要问我的感觉,关于上面三段, 我觉得他比较极端一些, 但是我还是部分的, 或者在一些句子上, 大部分的, 认同他的看法的。 另外就是, 这仅仅是一个访谈, 可能缺乏论据和论证, 不过如果看过Knuth的书(虽然我反对他的书是一般程序员的“必读”项目)就知道, 他是一个严谨的人, 敢这么说, 就一定是有自己的思考和认识的。 否则他也犯不着如此尖锐不是? 有时候我觉得, 包围我们的世界, 似乎是个虚假的世界, 如果不经常四处溜溜, 好像周围就让某些言论充斥了似的, 这很不好。 我以后会多注意反潮流的文章, 并介绍给大家, 也希望其它和我一样心存疑虑的人, 共同完成这项工作。

嗯, 更多的, 就没啥看法了。

posted on 2008-04-29 14:37 怪怪 阅读(4318) 评论(36)  编辑 收藏

评论

#1楼    回复  引用  查看    

高纳德先生岂止一个顶俩?!
2008-04-29 15:15 | J [未注册用户]

#2楼    回复  引用  查看    

我觉得是高德纳的水平太高了,很多Practices其实是为了保证大众的生产力。如果一个神仙级别的人那么自然怎么做都是nb的……
2008-04-29 15:15 | Jeffrey Zhao      

#3楼    回复  引用  查看    

我也顶顶,不能顶二,我顶一个就行
2008-04-29 15:20 | 石牌村夫      

#4楼    回复  引用  查看    

顶一个.
2008-04-29 15:31 | 狼Robot      

#5楼 [楼主]   回复  引用  查看    

@Jeffrey Zhao
我觉得吧, 其实要是比组织人手做个网站什么地, 就是高老爷子年轻几十岁(认识水平不变), 也不见得比你我就强..., 嗯嗯

其实关键还是本质问题是什么。 我个人认为, 应用新的方法论, 不抓住本质问题, 也是白搭; 而抓住本质问题, 方法的选择, 就不那么关键了。
2008-04-29 15:34 | 怪怪      

#6楼    回复  引用  查看    

长见识了,知道了高老爷子。
高老爷子肯定比一般人都要高吧?
2008-04-29 16:00 | 李战      

#7楼    回复  引用  查看    

对不起啊,问个偏题的好不好。
你上次在“钢钢”的博客上发表大论,说可以实现一个通用的泛型的工厂来返回接口,以剔除”水蒸气业务逻辑类“的同时,隔断调用。
这个工厂怎么实现啊,才能做到通用。。。。
很迷茫。。。。。
评论如下:
“Employees_BLL" -> 水蒸气类, 可能唯一的好处是隔断调用, 万一以后变化的时候, 尝点甜头。 我的建议是不如去掉。 从调用方总结需求, 使用一个接口; 使用工厂来返回这个接口。

2008-04-29 16:11 | 汉广      

#8楼    回复  引用  查看    

我觉得,如果要说软件开发困难,最本质的原因就是客户的需求不明确,电脑的资源不够用,历史的遗留问题太多,项目的开发时间太短。而使之更为困难的是,需求,运行环境这些东西一直会变,基本没人能比较准确预测,而大家却经常要让在短期内开发的软件能在长期内“灵活”应对变化。我认为敏捷方法的很多思想是比较针对和适合当前这样的整体环境的,但是具体如何实践,大家还是应该根据实际自己剪裁,不一定非得全盘照搬。
2008-04-29 16:19 | deerchao      

#9楼    回复  引用  查看    

我也跑个题,这个页面在FireFox下,换行有问题,很宽,大约有1650px*1.8那么宽。
2008-04-29 16:21 | deerchao      

#10楼 [楼主]   回复  引用  查看    

@汉广
倒.., 说白了是个内存中的代码生成问题。

首先第一步就是定义接口啦,这步没得说, 用什么方法, 就定义啥。

第二是工厂。

对于那些转一次调用, 是没有必要弄出一个类的, 我们只是为了让调用者不知道接口下面的东西。 这样的话, 在工厂中, 我们完全可以直接返回数据操作类, 当然, 这要求数据操作类必须实现了接口。

如果相关工作量很多,或者要在数据获取前后加上一些不属于数据层的通用操作, 我们可以把它们泛化。

工厂肯定是这样: Factory<T>.Create() 或者Factory.Create<T>();

T是被返回的接口, 由第一步定义, 由使用者传入。

由于我们有了T, 这样工厂就获得了类型信息。 同时我们也知道数据操作类(可以通过Provider之类的, 最简单的就是一个死类啦)的类型信息。 如果T和数据操作类是一一对应的, 我们可以遍历接口上的方法, 然后用emit或者生成C#代码动态编译在内存中构建一个符合接口并调用数据操作类对应方法的类并实例化,返回给调用者。 需要注意的是, 我们要缓存这个内存中的类, 这样emit或者动态编译只进行一次, 其性能损失就可以忽略不计。

对于加入通用操作, 比如, 生成的"Employees_BLL"就是这样。

public Employee GetPerson(int id) {
Log(通用)
if(Cached) return from Cache
向数据操作类获取数据,
Cache(通用)
}

其实只是比转发多一些生成通用代码的工作。 但是我们可以考虑, 由于Log和Cache可能变化, 未来也可能增加新的通用操作, 可以改成生成这样的代码:

public Employee GetPerson(int id) {
1.获取数据前通用逻辑的调用
2.向数据操作类获取数据,
3.获取数据后通用逻辑的调用
}

最前面和最后面的, 可以生成通用的方法调用, 比如触发事件; 我们可以通过事件机制来配置前后的调用。 当然在设计上要有所考虑, 比如如果对象Cache了, 我们要在步骤1返回, 就不进行数据存取了。

这样, 生成的动态类的形式就可以完全固定, 而通用操作就变为可配置的了。对于调用者, 这一切它都不会知道,它只对接口操作就可以了。

至于具体如何生成代码, 你可以看看网络上关于Emit和生成C#代码动态编译的文章。 我个人倾向于前者是因为, Emit会给我带来克服困难的快感。 其实后者用理智判断的话, 更合适。 因为我们甚至可以做出C#代码的模板, 不但把生成工作变成简单的字符串处理, 由于模板可以随时编辑, 我们还获得了改变的灵活性。

如果接口上的方法, 不见得再数据操作类上可以找到相同签名的方法, 我们可以使用配置文件, 告诉这个在内存中生成类的东东, 接口上的方法对应的数据操作类是哪个, 对应的方法是什么。 虽然配置也打了字, 但是那些通用的工作的字我们就不用打了, 关键是我们能找出多少重复的代码, 还有如何识别重复, 归并同类项。 对于一般的基于这种结构的系统, 我们可以把非常多的通用和重复的流程、 操作, 通过这些技巧简化掉~

这个如果你还有疑惑, 等有时间了, 我做个小例子出来(不是保证, 我说话比较没谱... -___-)。

@李战
肯定比我高就是了....
2008-04-29 16:37 | 怪怪      

#11楼 [楼主]   回复  引用  查看    

@deerchao
果然如此,Safari下没问题我就以为FF不会出问题了..

这么简朴的主题还会存在问题..., 懒得加css了, 等着dudu他们改吧。
2008-04-29 16:45 | 怪怪      

#12楼    回复  引用  查看    

knuth是超级完美主义者,如果让他组织开发一个网站,一定是最后连操作系统、Web Server、数据库、脚本语言、执行引擎都统统开发出来并且提出和解决了10个以上计算机领域的难题……
2008-04-29 16:46 | 装配脑袋      

#13楼 [楼主]   回复  引用  查看    

@装配脑袋
逮着你了.., VB和XML的文章呢?

2008-04-29 16:48 | 怪怪      

#14楼    回复  引用  查看    

@怪怪

5555……
2008-04-29 16:50 | 装配脑袋      

#15楼 [楼主]   回复  引用  查看    

@装配脑袋
我做的板凳腿都快折了..
2008-04-29 16:52 | 怪怪      

#16楼    回复  引用  查看    

@怪怪

老实说,我最近找到了一个XLinq很好的用途,但是要彻底完成是个很大的项目,我没有精力做。只是介绍普通语法不是我的目的。而且我最近兴趣都放在编译器开发上了:P
2008-04-29 16:57 | 装配脑袋      

#17楼    回复  引用  查看    

我把MSN放在“只有博主才能看到”的Email栏了,加一下方便以后交流吧?
2008-04-29 16:58 | 装配脑袋      

#18楼 [楼主]   回复  引用  查看    

你的联系方式给我发个短消息。 我发现我老是步你后尘..., 你都开始玩了, 我还在犹豫 -___-
2008-04-29 16:58 | 怪怪      

#19楼 [楼主]   回复  引用  查看    

呃..., 连交换联系方式这种事, 你都比我领先一步 -__-

加好了~
2008-04-29 16:59 | 怪怪      

#20楼    回复  引用  查看    

2008-04-29 17:14 | 万一      

#21楼    回复  引用  查看    

2008-04-29 18:08 | JackLee      

#22楼    回复  引用  查看    

俺来看看老高对并行有啥看法,:-)
2008-04-29 18:28 | Angel Lucifer      

#23楼    回复  引用  查看    

明白一点了,谢谢怪怪:-)
2008-04-29 19:10 | 汉广      

#24楼    回复  引用  查看    

关于Donald Knuth,你可以先引用我的这篇《Donald Knuth 简介》
http://www.cnblogs.com/xugang/archive/2007/10/03/913350.html
^_^

@汉广 不要踩了我的那颗地雷哦 呵呵

2008-04-30 00:21 | 钢钢      

#25楼    回复  引用  查看    

@怪怪兄台
牛人牛不牛这个还没有到我讨论的程度,在这里我只想对一些您回复钢钢所做评论提几个问题。您前面回复汉广兄弟的我就不再问了,当然对那块现在也还不是很明了,有可能后面会麻烦您
您提到对于域模型取消的问题,不知您的概念是特指取消ActiveRecord 还是包括比方说由两个或更多类组合而成的类?您提到用LINQ代替领域模型,假设是读取记录,这个我想使用LINQ查询的时候使用匿名类型问题应该不大,假设是新增记录呢?难道要使用LINQ查询一次返回一个对象,然后在界面层修改属性?
LINQ这个东西我了解不多,要学的东西太多了,有点顾不上,谢谢您?
2008-04-30 00:37 | songcan      

#26楼    回复  引用  查看    

“大家追潮流追的也不少了...最后才发现都是一场空。”这一段写得太tm的好了。赞博主一个。
2008-04-30 00:50 | yushih      

#27楼 [楼主]   回复  引用  查看    

@songcan
不是我不想把那些问题说清楚, 确实是表达能力不佳, 时间也有限, 另外我想技巧类的东西也不是我的强项... (事实上, 我仔细一数, 似乎没啥真正的强项..)

“由两个或更多类组合而成的类”,这个我不知道你指的是啥, 我指的其实是取消, 实际上是两个东西:

1. 类似于ActiveRecord一类的所有DTO, 既只用来运输数据, 自身不会有什么计算的, 比如大多数不太复杂的CMS里的Post/Article这类东西。

2. 叫做业务逻辑, 实际上仅仅是转发, 或者, 更多一些, 插入一些和业务逻辑不相干的操作的水蒸气类, 这种类往往更接近于边界对象。

当然, 对于可能含有一到两个简单逻辑的东西, 你很难说它是不是DTO, 但是如果它的DTO意味太浓了, 那么不如把逻辑单分出去, 实际上, 数据和算法分离, 也是一个很强的流派, 对于我们这些凡夫俗子, 怎么省劲儿怎么来。

当出现真正的逻辑对象需求时,我们可以从运输物中提取, 使用运输物承载的数据制造,或者包装一下运输物, 采用一个新对象, 在逻辑中处理那些逻辑关心的问题的相关数据。 而不是因为一个对象既发挥DTO的作用, 又在逻辑中占有一席之地, 就把它们掺和在一起,从而那些仅仅发挥承载数据的属性也被误认为是合法的, 最后弄出一个7分DTO,3分逻辑对象的东西。

我说使用Linq, 就是说使用Linq自己生成的DTO,我的意思只是不必要为了自己的系统符合某一框架, 自己去制造和处理DTO。 部分认可这个方案的原因是, 至少这些工作不是咱们自己付出的工作量。 估计是这块和取消DTO之间的矛盾让你误解了, 我残疾的表达能力啊...

而且我这话说的有点多余, 如果让我做个倾向性的意见, 说实话, 我认为除非感受到强烈的需要,最好不要使用Linq中的ORM部分或者其它ORM。 因为它们很可能会阻碍你在其它方面本来可以进行的设计, 从而得到的那一点点甜头, 还不如失去的东西多。 也许另一种设计减少的工作量, 远大于Linq ORM甚至对象化能提供的强类型、代码提示、 属性导航什么的所降低的工作量。

但这些都是有特定条件的, 既我们确实无法在内存中保有所有数据, 绝大多数数据还是在持久中, 并且主要工作量实际上就是来自于CRUD。 那么我们针对解决的问题, 很可能就不是什么业务问题, 而就是如何更好的CRUD和显示的问题。 这时候实体们不碍事, 就已经很不错了....
2008-04-30 02:15 | 怪怪      

#28楼    回复  引用  查看    

飘过。。。
2008-04-30 04:44 | demomyy [未注册用户]

#29楼    回复  引用  查看    

俺觉得方法论也是“没有最好的,只有最适合的”吧……
就像中国足球队,连最基本的传球、射门这些基本功都不扎实,连续传球很难超过3脚,再讨论应该使用英式打法还是南美打法岂不是笑话么?
另外现在流行的方法论似乎都是以开发出高质量的程序作为目标之一,而国内很多公司都是把最小化开发时间和费用作为目标(虽然嘴上都不愿承认),这也是个矛盾。
2008-04-30 09:01 | 1-2-3      

#30楼    回复  引用  查看    

真是一语惊醒梦中人啊,呵呵,TDD虽然是好东西,用的不恰当也是累赘。没有完全可靠的代码,也没有完全可靠的测试。所以只在最需要的地方测试就行啦。在想探寻事情究竟的时候测试就行了!
2008-04-30 10:05 | 镜涛      

#31楼    回复  引用  查看    

>>我也不见得抓着你的脑袋使劲儿晃(让你清醒)
一个同时就对我做了这样的事情,结果我尖叫了一声晕倒了。

其他的没看懂,呵呵。
2008-04-30 10:40 | jyk [未注册用户]

#32楼    回复  引用  查看    

Donald.E.Knuth:http://baike.baidu.com/history/id=1981485
2008-04-30 11:01 | 青羽      

#33楼    回复  引用  查看    

"我觉得是高德纳的水平太高了,很多Practices其实是为了保证大众的生产力。如果一个神仙级别的人那么自然怎么做都是nb的…… "

同意。:-)
而且我觉得神仙级别的很多做事情的方式不是大众能够容易复制的。
BTW:
"Knuth访谈: 老将出马, 一个顶俩 " 不明白这个标题是什么意思,感觉起这样的标题是个噱头。
访谈的表现的主题显然不是表现:老将出马, 一个顶俩。而且这个文章的主题也不是。

2008-04-30 11:32 | Jeffrey Hua [未注册用户]

#34楼 [楼主]   回复  引用  查看    

@jyk
我估计要是我, 肯定突然一紧张,就发疯似的耍王八拳了...

@Jeffrey Hua
高老爷子的方法不容易复制, 明星梯队的方法照样不那么容易复制的。 其实就这件事, 国外大多数支持明星梯队的同志看法也都是, 我们不是高德纳, 我们做的事和高德纳不同。 这样的言论没法一个一个去辩论的。 就像高老爷子自己说的, 各信各的就好了; 人家不是说了, 退潮时, 才知道谁在裸泳么?

我一个顶俩的意思, 就是你看, XP给否了, 黑箱复用否了, 并行也被浇凉水了, 就像一楼说的, 一个顶俩, 那还是少说了...
2008-04-30 14:56 | 怪怪      

#35楼    回复  引用  查看    

我以前一直以为自己特别老土,Unit Test 用不上,黑箱代码也不敢用,连极限编程是什么都不知道。这会儿好,我终于找到老土的理由了。。。
2008-04-30 17:14 | 随风流月      

#36楼    回复  引用  查看    

极限编程本身是有局限性的,其实极限编程只是敏捷开发众多方法的其中一种方法,他的很多实践准则未必能适合所有的团队,可能是极限编程近来吹的挺火的,以至于很多人都以为极限编程=敏捷开发,至于为什么极限编程那么注重单元测试,原因就是极限编程的一个核心就是TDD(测试驱动),如果在做项目的时候不用TDD,那么则不需要每个功能点都要做自动化单元测试用例,否则,还是最好遵循TDD的步骤走下去,因为只有一套完整的自动化单元测试,才能有效支持后来的代码重构。
所以,XP有用还是没用,就要看怎么用他,完全否定他不行,完全照搬,也不行。单元测试本身没错,也许高老爷子认为为每个功能点都做单元测试有些浪费,但XP的实践者认为,这些浪费会在以后的变化更改中得到补偿。
再说说敏捷开发,敏捷开发的一个核心目标是:快速交付可工作的软件。而XP是用他自己的一套来实现这个目的,同样,FDD(特征驱动开发)、自适应软件开发方法等,也有自己一套来实现这个目的,当然,我们自己也可以在项目开发中创造出一套方法来实现这个目的。我觉得这才是敏捷开发的本质。
2008-05-01 19:45 | spgoal      

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-04-29 15:27 编辑过
 
另存  打印
最新IT新闻: