怪怪 | Nothing, Everything

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

2008年2月26日

有一点我不得不思考的

有空了解一下OWL,看看是不是能给我的一些想法新的启发。初步的看, 似乎有点掺杂着一些不纯洁的概念。不过,Ontology的概念还是很明确的:

引用本體論譯自英文ontology,又譯存在論或是論,它是形上學的一個基本分支,英語詞ontology是來源於希臘語單詞ον(存在)和λ?γο?(學問)的組合。ontology主要探討存在的本身,即一切現實事物的基本特徵。

有的哲學家,如柏拉圖學派認為:任何一個名詞都對應著一個實際存在;另外一些哲學家則主張有一些名詞並不代表存在的實體,而只代表一種集合的概念,包括事 物或事件,也有抽象的,由人類思維產生的事物。例如「社團」就代表一群具有同一性質的人組成的集合;「幾何」就代表一種特殊知識的集合等。

ontology就是「研究到底哪些名詞代表真實的存在實體,哪些名詞只是代表一種概念」。所以ontology成為某些哲學分支的基礎。近年來,人工智 慧及資訊技術相關領域的學者也開始將本體論的觀念用在知識表達上,即藉由本體論中的基本元素:概念及概念間的關連,作為描述真實世界的知識模型。針對此一趨勢,W3C組織也開始定義了許多Ontology的相關語言,如RDF、DAML+OIL、OWL等。

为了统一性, 如果实现一门用于描述的语言, 可以忽略一个名词都对应一个实际存在这一分支, 而是加入一层, 认为每一个名词都对应满足一组条件的集合。 这样就和面向对象彻底分道扬镳了: 类也好什么也好, 只是一个方便我们组织和使用的别名, 没有更多的意义; 而每一个实体都是被用各种特征织起来的。 同时,面向对象中接口这样的鸡肋概念也可以去除, 而只检测一个实体是否满足条件。 这样, 静态语言的检查可以得以保留, 同时还可以延伸出自动推导等更高级的组织方式。

这也是我目前和脑袋的分歧所在, 脑袋更看重可行性, 认为借助CLR和保证与CLR上其它语言的兼容是必要的做法; 鉴于底层模型和其它语言接口要求的限制,这样就没有办法实现类似于C++模板的功能。 而我虽然更菜一些, 但是反而更“不切实际”,希望在这上面有所突破。 到底应该如何选择呢? 有没有变通的做法呢?



另外,早期和我有交流的, 还有我那失败团队里的家伙们应该知道,其实我的Web框架本身、框架想要支持的产品和当初我设计的商业模式, 基本上和后来从FaceBook开始的这一大堆平台战略相类似。 现在说啥都没劲了。 我需要考虑的一个问题是,到底是因为我进度慢, 还是这个事情, 小团队根本做不了? 说实话, 我不太相信后者; 我自己的分析是我的自我管理能力和执行力还需要锻炼, 对集中式应用缺乏应有的信念、对如何进入市场心存疑虑。

另一个具体的延误是,在Web框架到产品这一层, 对界面组装的灵活性和行为划分的严格性要求太高,而我一直没找到让我心满意足的设定,导致一直迟疑不决。从DNN到Weebly到现在的这帮家伙,人家更 NB的组织都知道先弄个能转的东西放出去再说, 我是不是太机械和2B了? 这个地方我很确定不是因为自己的技术无法支撑, 所以应该集中反思产品策略问题,“黄金圣斗士不会被同一招数击中两次”, 我想我需要谨慎的思考。当然,也不能一概否定: 如果不是这种性格, 我也不可能不断的获得很多思考和提高; 所以主要是,在哪儿较真, 较多少真的问题。



我到底是不是一个真正的技术人?

我想成为一个顶尖的技术人, 但:

1.这个想法, 是真实的吗?

2.我相当的能说废话, 一个说废话的人, 其性格适合做一个技术人吗?

3.我没有专精, 而是每一个接触的方面, 都达到比第一流差的那个水平, 这是一个好事还是坏事?

希望跟我有接触的朋友们, 帮我观察一下, 并提出建议, 越难听越好。

posted @ 2008-07-08 01:55 怪怪 阅读(325) | 评论 (4)编辑

昨天到今天也很高兴

     摘要: 作为技术人员, 我要把这本非技术的书, 放到SICP之前;作为德鲁克的崇拜者,我要把这本书放在《卓有成效的管理者》之前来;作为佛洛伊德、荣格的初步接触者,我要把这本书放在《梦的解析》、《现代灵魂的自我拯救》之前;作为巴尔扎克、陀思妥耶夫斯基的忠实读者, 我要把这本书放在他俩的一切作品之前;我甚至会把这本书放到老庄之前: 是的,这只是一本相当业余的小书,不乏一些不求甚解的成分,甚至也稍嫌肤浅且有点八卦; 但凡是围绕人的著作,没有一本对于一个像我这样的平凡人而言, 更加有实用价值了。

作为一篇全是八卦的博客, 我认为我有责任作为这本小书的枪手,把它推到首页,只希望其它人也能分享这份喜悦。 也许它并非完全和技术圈子是无关的: 很多兄弟对从业的感受和迷惑, 说不准能从这本书中找到答案。 这本书的名字叫做《遇见未知的自己》。  阅读全文

posted @ 2008-07-07 08:04 怪怪 阅读(2479) | 评论 (49)编辑

资料

http://en.wikipedia.org/wiki/Comparison_of_BitTorrent_software

http://en.wikipedia.org/wiki/Comparison_of_eDonkey_software

posted @ 2008-07-05 03:39 怪怪 阅读(885) | 评论 (1)编辑

妈的

最近的一些感受。

首先,deerchao说的是对的, Community Server 2008要比2.1强太多了, 当然, 对于我来说还是不够好; 不过, 既然我自己没有能力拿出一个若干万行、并且好多人都在用的产品, 我就别他妈的JJWW了。 这件事的一个想法是: 有谁愿意提炼和修改Community Server 2008的,我愿意参与,我的想法是:

1.继续精简和重构。
2.改进对中文的支持。
3.重新开源之。

为了目标1和3,一些代码不妨重写。 这样的产品, 难说什么专利, 只要重构的程度跨过某一水平线, 版权不是什么问题。

第二件事, 我为了试一个软件是否存在时间过期, 调整了系统时间, 重启前也忘了改回来; 结果Windows 2008让我激活, 在这里提醒一下那些像我一样靠240天评估期使用非盗版Windows的同志。

第三件事, 重装的时候, 忘记旧软件应该先装, 比如Sql Server 2005应该在Visual Studio 2008之前。 有时候一些最简单的事情也会犯错, 所以细心和把细心的结果形成习惯,还是必要的。另外, 了解了一下Installer安装组件和Hotfix的思路, 发现一些问题还真是难处理;初步感觉,其实我们自己设计真正的软件时,也可能会碰见类似的问题,看看能不能沉淀一下,变成可以触发的联想的知识和经验。

第四件事, 我决心调整重点, 把Web框架作为次要工作了,我现在就必须开始P2P的研究。 从06年年底开始到现在, 一直没进入真正的产品阶段, 我想这绝不光光是因为我懒, 而是存在深层次的问题。 分布式、非集中的网络,才是我的信仰;我是不是真的愿意做Web框架,还是因为从事过一些Web开发就习惯性的走到这个道路上,我没法去分析清楚。

但是我自认对Web开发的方方面面,有一些体会还是很准确的。我希望我的实验成果还能为别人发挥一些作用,所以我还会把它当作一个副业继续。也许这样,心态反而会变好,作为一个副业,效率比这1年半还高也不是不可能的事情。

关键是了解自己,管理自己,这才是重中之重。

Update:
多加一件事, ATI的程序员不是人。 就是因为有了这样的程序员, 一般群众对.NET的印象就越来越坏。

posted @ 2008-07-02 07:53 怪怪 阅读(1829) | 评论 (9)编辑

最近回帖整理:

原帖,针对第四点:

看看客户所说的话, 能不能整理为一个自然语言的子集:与业务相关的小语言,并形式化。 实现过程可以三步走:

1. 对需要变化的业务规则建立统一的模型。

2. 使用解释器模式配合配置文件来表达小语言,应对变化。

3. 当2变得复杂和难于掌握, 考虑实现一门业务小语言, 难度较深。

纸上谈兵, 没机会实战过, 而且我估计这个成本对于承接项目的公司恐怕难于接受; 除非在市场上有多家公司需要这种东西, 这样算是预支成本吧。

对于一般技术人员, 可能认为难度在于实现小语言。 其实最难的一部分是如何将业务规则及其变化归纳为一个可接受的表达形式。

posted @ 2008-07-01 06:17 怪怪 阅读(1886) | 评论 (4)编辑

怪怪论三国:到底该关注些什么

发现博客园对三国感兴趣的人很多,不过关注点似乎和我都有所不同。要是让我看,三国时期只有一个英雄那就是曹操,除此之外就只剩下层次高低不等的流氓及其团伙一干人等。说实话,曹操身上最大的一个弱点,或许就体现在“天下英雄唯使君与曹尔”这句话中了,这说明他的精神境界中还有一些和刘备一样低劣的东西,如果曹魏最终的衰亡真有曹操自己的因素的话,恐怕就在这里了。

有人说三国志中曹操传比别人长比别人详细, 是因为作者以魏为正统, 个人不以为然: 比较一下职业生涯中,在动作的大小和频率方面,刘孙与曹操之间存在的不可弥补的差距, 就可以知道刘备、诸葛亮等作为与日月争辉的星星,不过尔尔。 有兴趣的, 以对于孙刘而言是大动作的粒度, 对曹操阵营的动作做一个列表, 比较一下三者的长短, 再配合时间轴一看, 这些都一清二楚。 这个故事本来一点也不复杂, 只是后面那些只知道拿三国吃饭的学者们把它弄复杂了。

很多人关注三国,着眼于做人,比如曹操所谓的权谋, 这实际上只是旁枝末节。 曹操此人身上所蕴含的巨大而无可匹敌的能量,才是真正无法忽视的根源;即使他做事方法变一个样,结果也不会逆转。 曹魏的命运, 也许可称的上“天亡我, 非战之罪”。 这个问题我没有足够的知识与能力关注,只说两点: 曹虽然起家于官宦家庭, 但其势并不比陈胜吴广项羽刘邦更好;客观历史环境所导致,那个时代的创业者比任何一个其他时代需要做都要多,以他的寿命是无法完成的。

要说做人,我们真正要看到的是,曹操做事情的节奏;我们还不能忽视的是, 无论作为政治家、军事家、社会活动家、文学艺术家,曹操的杰出成就的总和,可以说在中国历史上是数一数二的。 就像数学家标榜的“人类心智的荣耀”,和所有那些取得成功的人所真正留下的宝贵财富别无二致的,他的一生展示了一个人可以达到的极限有多远。 有些人可能认为,像文学艺术这样的东西,和曹操的成功失败没有必然联系,但事实上,正是曹操的内涵决定了他是一个什么样的人。

那些只注意权谋、机巧的人,是不可能走上和刘邦、曹操这样的人一样的道路的。 简单地说,像他们这样的人,好比上了发条的机器,没有停止的时候;而且他们通过训练,可以让动力衰竭的速度,控制在一定的范围内。当一个人在一条道路上,相对时间相展开到绝对时间上比其它人多好几倍,他注定要比所有人强。 这才是历史给我们上的第一课,没有这一课,纯粹的认为(类似的)老毛之所以是大家的头儿,是通读了二十四史或有什么其他杰出才干,是毫无意义的。

孙武告诉我们说,以正合、以奇胜,这已充分说明了孰在前、孰在后。 把周遭的人和事情想的特别复杂,并且和历史对照,在我们有足够的“正”之前,未必是什么好事。作为我们文化历史中的重要组成部分,对刘关张和诸葛亮的褒扬,对曹操“奇”的一部分的过多关注,过去几百年来对我们的民族是贻害甚巨的;这种传统掩盖了最重要的东西:如果一个人没有掌握真正的内在因素,就沉迷和训练自己什么做人、领导的艺术,哪怕就是极端的小人也不能成为合格且成功的大坏蛋。

我们首先要注意的是那些不平凡的人身上积极向上和光辉的一面,他们告诉我们一个人通过自身的努力可以换来什么样的奇迹,这才是属于全人类的骄傲。虽然作为一个普通人,拿我们和BT相比似乎没有什么意义 -- 但我认为,这些才是每一个想改善自己,取得更大成就的人所要关心和学习的; 至少借由这种鼓励,我们可以去尝试突破自己, 这才是真正的榜样的力量。

posted @ 2008-06-29 08:35 怪怪 阅读(3878) | 评论 (49)编辑

闲逛, 看见这么一句话

很随机的不小心进入网上一个不知名的博客,其随笔里提到的,他似乎是个经济学的研究生什么的。

此人说道我站在马克思的“生产力决定生产关系,生产关系制约生产力的发展”的观点上去解释组织的起源,而非交易费用节约的角度,交易费用节约只是组织的功能,拿功能来解释起源就犯了“功能主义”的错误。

嗯嗯,有意思。很显然我没必要去和他比他们领域内的知识和能力啦,不过还是有些额外的思考。

过去我也是信马克思的,而且,“生产力决定生产关系,生产关系制约生产力的发展",这一简单基本的观点,我现在也在用。但是随着我自己的世界观的形成,我似乎开始有了变化。
使用新的世界观,就不会简单的给不同的角度扣上各种大帽子。从交易费用节约的角度上看,真的是所谓的功能主义吗?即使是,功能主义背后所隐藏的东西,会不会比马克思的观点更朴素更基本呢?

有一个防雷的经验,就是说,如果在雷电击中你的那一刻,你抬起的是左脚,你比较不容易被电死。说实话,我是一个驽钝的人,想了好一会儿才明白为什么:电流想要流入地面,必须从右脚过去,这就有一定概率让电流避开心脏了。但我们不要忘记另一个事实,雷电是击穿空气打到你身上的,那为什么它不击穿你左脚和地面之间的空气呢?

这个道理非常简单,上过初中就学过,电流倾向于从电阻更小的地方通过;由于空气的电阻大大大与我们身体的电阻,它不会去选择击穿空气。我这些描述,细究的话,错误百出,而且很不严谨的拿电流当作了主语;但它在大体上是那么回事。这体现了一个非常基本的规律,就是能量最小耗费的原则;同样,作为更适合当主语的人,如果在获取的信息足够的情况下,我们也会执行最省事的一个方案。

我们可以考虑,如果人类和电流没有这种共同性,恐怕在物竞天择的自然界中,我们早就被淘汰了。所以我们可以认为这是宇宙本身的意思,它告诉电流那么做,也告诉我们该怎么做。我们并不需要高深的哲学和复杂的科学,只要愿意去多了解一些,就可以很不严谨的建立起一套正确概率还算不错的指导方针。

马克思的观点在这里,其实恰恰不是原则,而是结果。
我们把“组织”等同于某一种生产关系, 这种生产关系之所以产生,必须符合来自宇宙的指导,这些指导之一显然就包括能量最小耗费原则:我们可以想象,一些领域内活动(不止交易),在某一生产力和其它可能存在的条件下,一种生产关系会比另外一种生产关系更加节约,那么节约的那种生产关系就会屏雀中选。

我这样的说法,和单纯的交易费用节约又有很大不同,但是仍然可能是功能主义的:因为实际上是“节约”这一功能在前,生产关系的起源在后;是为了节约才有组织,而不是有了组织才节约;如果浪费是组织必然行使的功能,组织这种生产关系还能有起源吗?这也就是亚里士多德所说的目的因。另外,我对它的使用本身,就符合了能量最小耗费原则:针对我所需要掌握的程度,这种解释方式可以让我使用更少的能量去琢磨它。

马克思的总结中,还有一些其它因素,比如生产力,为什么生产力会发展呢? 马克思怎么回答的我已经忘了,但我也有自己的答案,不过,那就是另外一个故事了。总而言之,“生产力决定生产关系”这样的结论背后,其实可以挖掘的东西很多,如果纯粹把它本身当作一个锤子,看什么都是钉子,就非常有问题了。

最后多说一句,我不是唯心主义者,仅仅是选择了这样描述。

posted @ 2008-06-28 06:49 怪怪 阅读(2515) | 评论 (10)编辑

从DDD说开去,流行方法论和我们的未来

     摘要: 也许这就是人类做事的解决之道: 既然我们的社会还不具有一大堆能够将现实世界的问题和真正艰深的科学理论联系起来的顶尖工程师,也没有出现一群真正的大师拿出对大多数问题解决方案的总结,而事情总是要做的, 那么不如一步一步的来, 让菜菜鸟们跟随菜鸟的优雅,采取次一等的做法总是要比什么都不做来的好得多。所谓山中无老虎, 猴子称大王, 就说明大王存在的必要性了。  阅读全文

posted @ 2008-06-27 05:17 怪怪 阅读(3745) | 评论 (53)编辑

路过的说说, 我那篇文章, 应该发么?

说实话我有点疑惑, 不知道这样做对不对, 虽然那是我的真实想法。

这东西有趣。 设计产品的都去看看。

http://blog.seattlepi.nwsource.com/microsoft/archives/141821.asp

是一封披露的电子邮件, Gates讲述了在Microsoft.com下载Movie Maker的可怕经历, 以至于写了这个邮件敦促改进。 如果Gates都是这个感受, 那么我们设计产品时应该什么样呢?

posted @ 2008-06-26 23:57 怪怪 阅读(1068) | 评论 (0)编辑

也谈优秀: 我们真的必须知道什么吗?

     摘要: 工程人员绝对不要期望自己像研究人员一样生活和工作, 一旦达不到就抱怨。 要知道我们的工程时间, 和我们的生命都是有限的, 而一个工程人员有做不完的事情。如果不停的学习, 大多数时候不过是从一个表面到另一个表面的浪费时间, 所谓的“深入”,不过是个自我欺骗的屁话。   阅读全文

posted @ 2008-06-24 18:24 怪怪 阅读(3890) | 评论 (55)编辑

临时笔记, 有意思的东西

一些编译器理论的简单介绍,和现代Parser研究的新进展。

http://www.antlr.org/article/needlook.html

http://citeseer.comp.nus.edu.sg/440034.html

Tomita(GLR) Parser

Packrat parser (use TDPL)

http://java.sun.com/docs/books/jls/first_edition/html/19.doc.html

http://www.cs.berkeley.edu/~smcpeak/elkhound/

http://www.mollypages.org/page/grammar/index.mp

http://lambda.uta.edu/cse5317/notes/node20.html

http://pages.cpsc.ucalgary.ca/~robin/class/411/LR.1.html

http://en.wikipedia.org/wiki/Memoization

http://en.wikipedia.org/wiki/Comparison_of_parser_generators

http://en.wikipedia.org/wiki/Parsing_expression_grammar



> The author states that he wrote the GLR parser generator solely to
> handle C++ language spec [and someone lapped it up to handle Java].
>
> What exactly is it about OO languages that an LALR(1) parser cannot
> handle?

As the moderator noted, there is nothing about "OO" languages that
LALR(1) parsers cannot handle, but C++ itself is problematic. There
are LALR(1) and LL grammars for Java.

One of the problems with C++, is that expressions and declarations can
look exactly the same (technically, any language containing those the
or of the two productions is ambiguous) and C++ gets around that by
saying, if it looks like a declaration, it is a declaration (forcing
the "or" to be resolved in a particular declaration (and resolving the
ambiguity). However, that resolution is not expressed gramatically,
and one can not take two random context free rules and difference them
and expect the result to be a context free language, which is what the
C++ ambiguity resolution requires one to do.

In contrast, GLR grammars are not required to be unambiguous. Any
ambiguity is resolved by producing a resulting parse-forest that
represents all the potential mabiguous choices and requiring a later
"semantic" pass to choose which parse tree in the forst is the desired
one. Thus, with a GLR parser, one can disambiguate the C++ problem by
selecting the parse tree that treats all the ambiguous expression/
declaration sub-trees as declarations.

The only problem with GLR as a technology is that are no "warnings"
from the grammar processing tool that the language is ambiguous.
Well, there are warnings that the language is not LR (or LALR) or
whatever technology the GLR parser uses as a base. However, some of
those grammars will actually not be ambiguous and some of the will be
ambiguous. However, in any case, once your GLR generator has given a
warning, one either must prove that the language actually isn't
ambiguous or write your semantic phase assuming that the language is
ambiguous and disambiguate the resulting forest.

It is worth mentioning that there are other ways of handling ambiguous
grammars. In particular, one can use predicates to resolve
ambiguities. Predicates allow one to take the difference of two
productions in a controlled manner. In particular, it is possible to
write a syntactic rules that says, try to parse this as a declaration
and if it isn't parse it as an expression. The difference between the
predicated and the GLR solution is that predicated grammars are still
deterministic. There are no hidden ambiguities in a predicated
grammar. If your predicated parser generator gives you an error, you
still have an unresolved ambiguity and if it doesn't the resulting
parser will always construct a parse tree (and not a forest).

I would be remiss if I also did not point out backtracking parsers,
which are another solution to the problem. In fact, all the
implementations of predicated parsers that I know of, use some form of
backtracking in their implementation. General backtrakcing parsers
share the characteristic with GLR parsers that they can parse
ambiguous grammars. Backtracking parsers generally also produce a
parse tree (although in theory they could also produce a forest).
Backtracking parsers have their own deficits though. Many
backtracking parsers will loop forever on some ambiguous grammars.
(Predicated backtraking parsers do not generally have this problem,
although they do not make the same linear time guarantees that pure LL
and LR parsers do(see note)--of course, any parser generator that can
handle a significant class of ambiguous must be inherently non-linear
for some grammars, and GLR parsers have a cubic worst case, same as
Earley parsers.) In addition, most backtracking parsers resolve
ambiguities by selecting one parse tree out of the forest to return.
This is generally done by the order of the rules in the grammar (which
determines the order the rules are tried in in ambiguous cases). If
one looks closely, this is very similar to using predicates
"implicitly" in the grammar. The key difference being that the tool
inserts the predicates rather than the user and does so without
warning and usually without the run-time termination guarantees.

I would like to mention that it is possible to build a predicated
parser using GLR technology, although I don't know of anyone
attempting to do so right now. From thought-experiments I have done
considering whether to implement such a tool, it seems like there
would be some advantages to building such a tool.

Again, I do not want to imply that these are the only techniques for
dealing with ambiguity. For example, Ralph Boland is pursing some
generalization of LR technology that I gather will handle a wider
class of languages and I don't think his technique is any of the
above.

Note: Bryan Ford recently published a paper on a "predicated" parsing
technique that made extensive use of memoization and lazy evaluation
to achieve (if I recall correctly) a linear time guarantee. His
technique shares a characterisitic with general backtracking parsers
in that the order of rules determines what is matched and the the
entire tree is disambiguated that way. He uses an "ordered" or clause
to implement this.

Hope this helps,
-Chris


Chris Clark said (in part):

> It is worth mentioning that there are other ways of handling ambiguous
> grammars. In particular, one can use predicates to resolve
> ambiguities. Predicates allow one to take the difference of two
> productions in a controlled manner. In particular, it is possible to
> write a syntactic rules that says, try to parse this as a declaration
> and if it isn't parse it as an expression. The difference between the
> predicated and the GLR solution is that predicated grammars are still
> deterministic. There are no hidden ambiguities in a predicated
> grammar. If your predicated parser generator gives you an error, you
> still have an unresolved ambiguity and if it doesn't the resulting
> parser will always construct a parse tree (and not a forest)

I agree with Chris about the use of predicates.

Interestingly, the use of predicates alone can some Type 1 power to a
grammar.

For instance:

L1 = {a^n b^n c+} // clearly a type 2 language
L2 = {a+ b^n c^n} // clearly a type 2 language

L1 intersect L2 = {a^n b^n c^n} // a type 1 language

Current research in the area of this class of grammars can be found here:

http://www.cs.queensu.ca/home/okhotin/

See the section on "Boolean grammars." Intersection can get quite a bit of
power out of a formalism.

My most recent paper deals with several difficult to parse languages of the
classical sort, including the particularly nasty to parse:

L = {a^m b^n c^mn}

The only grammar I've seen expressed for that one in classical form is in
Type 0 due to a length increasing production:

  (1) <S> ::= <H><S> | <H><B>
  (2) <B> ::= <B><B> | <C>
  (3) <H><B> ::= <A><X><N><B>
  (4) <N><B> ::= <B><N>
  (5) <B><M> ::= <M><B>
  (6) <N><C> ::= <M>c
  (7) <N>c ::= <M>cc
  (8) <X><M><B><B> ::= <B><X><N><B>
  (9) <X><B><M>c ::= <B>c
(10) <H><A> ::= <A><H>
(11) <A> ::= a
(12) <B> ::= b

Because production (9) is length increasing, the grammar is in Type 0 form,
even though the language itself is Type 1. I'd like to see that grammar
normalized to a Type 1 -- but haven't been able to find one.

The longest derivation I've been able to do with that by hand is aabcc,
which is:

(11) aabcc --> <A>abcc
(11) <A>abcc --> <A><A>bcc
(12) <A><A>bcc --> <A><A><B>cc
  (9) <A><A><B>cc --> <A><A><X><B><M>cc
  (7) <A><A><X><B><M>cc --> <A><A><X><B><N>c
  (4) <A><A><X><B><N>c --> <A><A><X><N><B>c
  (3) <A><A><X><N><B>c --> <A><H><B>c
  (9) <A><H><B>c --> <A><H><X><B><M>c
  (6) <A><H><X><B><M>c --> <A><H><X><B><N><C>
  (4) <A><H><X><B><N><C> --> <A><H><X><N><B><B>
  (2) <A><H><X><N><B><B> --> <A><H><X><N><B>
(10) <A><H><X><N><B> --> <H><A><X><N><B>
  (3) <H><A><X><N><B> --> <H><H><B>
  (1) <H><H><B> --> <H><S>
  (1) <H><S> --> <S>

I started on aaabbcccccc -- but got lost in the shuffle. :-(

If anyone wants to try a purely "predicate" approach to the above
language -- I'd love to see it. (Or if anyone would care to post the
derivation of aaabbcccccc, I'd really love to see that, too.)

The $-grammar I wrote for that one accepts strings in O(n^2.3), and has 6
productions and 2 of those are predicates, but also makes use of 2
phi-expressions, which implies a total of 4 predicates (since there is an
implied predicate with every phi-expression) and at least 2 name-indexed
tries.

Also of note is that I allow for a-expressions in predicates, which allows
for substrings that have been parsed to be concatenated to form entirely new
input that is then passed to the predicates. (The $-grammar for a^m b^n c^mn
uses this.) This is similar to what is known as "length-increasing".

Anyway, a few nights ago, I was asking myself about this formation in C++:

class Foo
{
int inline_function(int x)
{
return __y * x; // __y is used before being seen
}

int __y;
}; // this class is legal

class Bar
{
int inline_function(int x)
{
return __y * x; // __y is an undeclared variable
}
}; // this class is not legal because __y never gets declared

$-calculus was able to handle this ... without any code, accepting Foo and
rejecting Bar -- using all of the above mentioned techniques.

Although the resulting $-grammar uses more than 1 explicit predicate, it
does make use of phi-expressions, and these have implied predicates -- so I
was not able to do it without extensive overall use of predication.

Anyway -- I wrote it up and am looking for somewhere that is looking for a
3.5 page paper on such things. Any thoughts?

[BTW -- Chris -- direct email to you bounces from my account. Is that a spam
guard?]

posted @ 2008-06-20 20:30 怪怪 阅读(1773) | 评论 (0)编辑

方法级AOP: 又一个补丁

     摘要: 方法级的AOP的一种办法, 利用了新的Expression, 比起生成动态代理类那是清凉多了, 使用起来也灵活, 就是表达方式有点丑 :P

这是跟老赵还有脑袋讨论的成果, 感兴趣的可以进来讨论一下。 感谢老赵和他的文章的帮助, 同时也更深刻的感到如果语言的表达方式能提供足够的支撑多好, 大家一起催脑袋干活 :P  阅读全文

posted @ 2008-06-12 23:54 怪怪 阅读(4466) | 评论 (18)编辑

     摘要: 绝对有另你不适的内容, 不想反胃勿进; 基本上是一篇可以定性为“反人类罪”的发泄。  阅读全文

posted @ 2008-06-02 04:11 怪怪 阅读(4945) | 评论 (10)编辑

系列讨论初步考虑的备忘

     摘要: 先把一些相关的内容, 想到的目录记录一下。 这些标题是散乱的, 甚至不是一个层次的, 仅仅做一个备忘的笔记。

顺便说一句, 这个系列不是忽悠大家去用某一门“表达方式更丰富”的语言, 或者给出什么解决方案。 对于大多数程序员, 身处环境和项目当中, 更换语言是不现实的。 更何况说实在的, 现在还没有一门语言能够完美的达到我想要的效果或标准; 即使那些能够做到的语言, 我们可以采取的表达方式也是极其丑陋的。 并且, 在这系列文章的讨论所涉及的一些工作,如对语言本身的改进, 也不是大多数程序员任务。

但是我们仍然可以因为一些深入讨论, 知道问题的症结所在; 从而在能避开的时候避开, 在不能避开的时候, 不会殚精竭虑的去寻求不切实际的解决办法。 同时, 在这个系列中, 我们也可以找出一些外围辅助的方式处理好其中一些问题, 暂时不能治本, 指标也好。 更多的, 我们可以通过讨论,把现今那些浮躁的解决方案先放到一边,努力的去试着看清未来10年一些可能发展的方向。如果10年之后, 你我还在做技术, 即使没有预测准, 这样的尝试也不能说是无意义的。
  阅读全文

posted @ 2008-05-24 09:14 怪怪 阅读(5582) | 评论 (14)编辑

保存个地址, 顺便问个问题~

再更新两个地址:
http://programmersatwork.wordpress.com/john-warnock/
http://programmersatwork.wordpress.com/bill-gates-1986/

更新一个地址: http://www.infoq.com/articles/dsl-on-the-clr

地址: http://www.codersatwork.com/names.html?order=popularity

最后这个是个大牛列表 :)

问题:

具体点拿一堆图片的管理来说, 大多数系统, 都是有一个Picture表, 一个Category表, 一个链接表, 链接表就这两个字段: PictureID, CategoryID。

比如任何一个相册, 用户可能给一张图片一个分类, 但是也可能没给这张图片分类,这些没有分类的图片, 在咱们实现的时候, 是让他们属于“没有分类的图片(或默认分类)”这样一个分类呢?还是就让他们什么也不属于: 凡是用户没有指定分类的, 根本不在链接表内出现。

对应于数据库, 对于用户没有选择分类的情况,这两种做法区别在于在链接表内, 会不会有 {PictureID = 1 CategoryID = 默认分类ID值} 这样一行。

有默认分类的优势在于当用户查询“所有没有分类的图片(或默认分类的图片)”的时候,一句"Where CategoryID=默认分类ID"搞定了, 而且可以统一处理“没有分类,分类1, 分类2....”之间的区别。 劣势却仅仅是我的链接表里比不设立默认分类, 多出很多行。

我的想法是, 是否可以把设立默认分类当成一个最佳实践,无论建立什么系统时, 只要在实质上是一个分类的问题, 都可以采取这种实现; 因为这个问题普通到不再受其他条件的影响。 问题在于有没有不适合的反例,比如有默认分类在某种情况下更糟糕, 我想问的就是这个。

这个问题虽然简单, 不过从我第一次接触到现在7、8年来, 一直没有着急做出判断, 也是不敢轻易判断。 因为我无法判断从事情的本质来讲, 没有分类是不是就是一种分类; 这个问题和0到底是不是规划到自然数有点像; 所以对于我来说,这个问题的答案, 对我认识事物也许会造成连带的影响。

那么如果不说这些虚的, 光从实际出发, 设定一个叫做“没有分类”的分类来简化问题, 是否有存在着不适用的反例呢?

posted @ 2008-05-23 12:31 怪怪 阅读(5034) | 评论 (7)编辑

嗯嗯, 今天很高兴

今天(或者说昨天),见到了AnyTao、周银灰、丁学、 金色海洋、 jilzhang几个兄弟, 不过有一点不爽, 因为昨天休息不好, 老毛病又犯了, 一困就要滔滔不绝的说话,这个可能妨碍了大家更好的交流。 最后都到了我和丁学的大本营, 我还抑制不住兴奋, 拉住他又说了一根烟的废话, 完全没考虑到明天人家还要上班。 在这里向大家致歉。

jilzhang说的不错, 我写文章没有重点, 乱七八糟的东一句西一句, 我考虑是不是以连载或者书(不是出版的书)的形式, 把篇幅拉长, 并且根据我所表达的食物的前后依赖关系进行规划, 然后按部分阐述, 这样是不是能清楚一点。 还是怎么样, 希望大家多给我提提意见。 说实话, 就像大家说的, 每个人发文的积极性也有限, 如果我始终不能提高自己的表达水平, 可能也不会一直这样一团乱麻的继续下去。

还有, jilzhang对持续集成的实践的介绍, 破除了我因为不喜欢Fowler而对CC的反感, 这是一个收获; 我会找机会试试这个东西, 幸亏一直以来我对不熟悉的东西不会评论, 不然如此情绪化会影响正确的判断力。 大家也打破了我想办法混个更高的学历从而当个老师, 以赢得研究时间的不切实际的想法。 这几天我会思考一下, 是不是还是以应用出发, 带动研究。

说实话感觉在程序设计的哲学与表达上, 我应该有一定积淀去支撑我所中意的几个应用了; 反过来讲, 语言设计和编译器技术倒不是很着急的事情, 因为和那些语言作者相比, 我似乎还缺乏很多的体会, 包括制造一个语言的需求。 本来这些应用就是肯定要做的,也许我应该切掉好高骛远的期望, 针对目前可行的应用,全力以赴。 也希望能以这些实践为依据, 更清楚的表达我的理念和具体实践方法。

从AnyTao和丁学那里, 初步了解了某一个敏捷形式过程中的一些重点, 包括如何和客户打交道的经验等, 受到了不小的启发; 这些东西都是我目前的工作生活状况很难接触到的。可惜周银灰和海洋没我这么爱说话, 不过还是从海洋那里初步了解了他的思路。 并且, 一些海洋式的反问, 对我的牛皮也是很好的质疑, 让我注意到我对我的理论的实践和思考, 还存在着不少模糊的点。

总而言之, 今天是不错的一天。

posted @ 2008-05-19 01:51 怪怪 阅读(4745) | 评论 (10)编辑

为什么OO是有本质缺陷的?

今天我在这里说OO表达能力不足, 估计没人会信, 但是这真有可能是问题的核心所在, 如果是这样, 那么用歪了也罢学习困难也罢, 错不在使用者和学习者, 而在于OO自身(这种质疑也不是一天两天了,不过大多数言论都是外延法,强调主观因素, 所以不具说服力)。

这篇文章中的思路首先要归功于songcan兄弟刨根问底的精神和脑袋兄与我的讨论和对我的帮助。

废话少说, 说个关键问题吧。 OO最常见的就是 Teacher.Students, Teacher.Speak(), 也就是说Students和动作Speak作为Teacher的组成部分, 是我们关注的切实存在的概念, 但传统的OO居然没有给出向*系统*描述这个概念的表达方式。 是的, 你我都理解字面意思Speak, 可问题是这个概念在系统内不能表达, 我们就无法用其它机构来处理这些概念。

为什么C#加入delegate以后, 方便了许多? 因为Speak从某种意义上, 可以单独提出来, 作为一个在系统中的实际存在, 并且开始可以对它进行有限的操作了。但这还远远不够, 因为Speak是作为Action()存在, 它自身在业务中的独特性没有特别好的方式去表达。

另外一点就是动静间的鸿沟。 C#在Strustroup这些人的看法里, 并不属于真正的静态语言, 但是它给出了一个静态的外表。当我们进行描述时使用的是静态的方式, 我们就必须有静态的方式处理它们, 否则这里面就存在裂缝。 如果大量的反射, 那么我们何必不直接使用动态语言呢?

JS大家都接触过, 比如

obj["someAction"] = function() {}
obj.someAction()

那么C#拿着反射出来的MethodInfo搞来稿去,和JS的方式比丑陋的多, 这样的方式有必要去学吗? 如果一门静态语言, 大家越来越多的是在使用这些, 或者通过那些框架、工具间接的使用这些, 这难道说明这门静态语言, 或者基于这门语言的OO方法, 越来越强大不成? 只能说这种方法因为自身的问题, 无法继续提供足够的支撑了, 不得不求助于外部设施。

说实话, 如果一个语言, 表达重要的概念用到的那种表达方式, 比如类型, 它本身不能被操作的话, 那么它存在问题是必然的。 C#可以操作, 但提供的主要操作方式, 都在运行时, 通过反射。 可我们表达概念时, 却在编译前, 也就是说我们的表达注定是不完整的(或不直接的)。 反观动态语言, 为什么越搞越火, 还不是因为人家干脆都放在运行时了, 完整了; 而且在表达方式上优化过, 直接在语言层面支持, 这不是反射所能比的。

如果我每句话缺几个字, 大家感觉如何? 一个不完整的表达, 你觉得什么样的工具或者方法论, 让你能够毫无障碍的完成模型的建立呢?

P.S. 再次感谢以上二位和与我讨论过的各位。

另外, F#我也试过了, 这些问题全部存在(妈的,终于理解SICP某一页的小注释中质疑流行语言的类型系统的原因了), 根本是白搭: 实际上这本来与是否FP也没啥联系, 只是我希望作者按照脑袋兄跟我提出的那种意图和方式, 在编译器的层面做了一些改良。我的最后一线希望成了梦幻泡影。

我现在的建议是,要么选择一门动态语言, 要么选择C++和D(其实C++是个很差的选择); 如果暂时不能更换, 那就不要考虑太多了, 承认问题的存在, 并且尽量弥补就是(似乎.NET平台上的语言目前就是这种状况, 我自己也是在鉴于现实原因没法换的境地)。

最后重申一遍: 不要因为OO存在这样那样的问题, 就放弃OO的尝试。 我的想法是, 作为一种当代最流行的方法, 没有一定程度的了解是不行的, 就像牛顿定律一样。 所以我倒是认为, 对OO的深入思考和练习, 虽然一时疑惑, 也绝非没有好处的; 尤其是当我们知道它可能存在问题这一点, 就更可以放开心态了。

过去一个高人对我说, 想学好数学先学好数学史; 我数学史不咋地。 今天我要说我们有一个大好机会, 因为我们就在历史里(这个历史看来还要持续几年); 如果我们认为OO不过是个大忽悠,不屑于学习OO体现了自我相对于云云大众的明智, 那么明天会如何, 就不好说了。

剩下的, 就是等脑袋兄的编译器小改款出炉了, 大家一起拿鞭子抽他干活...

posted @ 2008-05-17 07:31 怪怪 阅读(3645) | 评论 (9)编辑

漫谈数据存取与对象设计

     摘要: 本文介绍了几个问题的某些特定的解决方法, 除了这些方法, 还有很多其它的方法。 要不要使用它们,关键在于我们对碰见的情况是如何判断的。 只是一概而论却忽视了衡量必要性、 适用性的工作是不行的; 进行判断的时候, 忘掉所有的面向对象原则和建模指南吧。 另外一个情况就是, 也许“程序本身需要组织和管理”的需求是突然发现的, 重构这一话题的流行,也足以证明一开始就固定一个漂亮设计的风险。

这也是一般程序员的饭碗所在, 如果有一个一劳永逸的方式, 那么它很容易被固定下来, 减轻工作量,可也意味着这些地方不再需要程序员了。  阅读全文

posted @ 2008-05-13 20:05 怪怪 阅读(3137) | 评论 (27)编辑

晕了

没事又琢磨下DLinq, 顺便关注了下Entity Framework, 总感觉是走在了错误的道路上。

整体工作量并没有下降多少, 而复杂度却在上升; 效率没有上升多少, 而灵活性却在下降。

如果说大公司是吃屎的, 跟随的都是挨忽悠的,这不是我的作风。 不是怕得罪人, 而是不客观。

我像是裸泳的吗? 糊涂中。

Update:
说点题外的, 很可能大多数时候我们对一件事物的执着来自于自我价值肯定的心理需求。 这种心理需求用好了,是成就自己的动力; 用坏了,就容易产生误导自己的错觉。

所以要谨慎、 谨慎、 再谨慎。看似针对外部问题的判断, 有时候恰恰需要仔细衡量的是我们的内心。

Update:
有个可以类比的思考: 我们刚接触ASP.NET的时候, 甚至DreamWeaver的时候, 感觉一切托托拽拽多么简单; 最后呢?

隐藏复杂度不等于更好的掌控了复杂度, 转移或转化问题不等于真正的减少了问题。

剩下的就在于如何分辨两者了。

posted @ 2008-05-12 11:41 怪怪 阅读(1072) | 评论 (8)编辑

我们应该讨论什么? 就面向对象的讨论所引发的一些思考

     摘要: 面向对象不是唯一的方法论, 也不太可能是最完善的一种方法论, 之所以流行, 其深刻原因也不是我们能回答的。 只是提醒大家, 有一种现象, 叫做劣币驱逐良币(我并没有说它一定是)。 但是无论好坏,现在面向对象的周边配套设施却是最齐全的, 考虑到这一点, 不逐渐深入掌握面向对象的各方面常识, 对于我们平时的顺利工作来说又是不行的。  阅读全文

posted @ 2008-05-11 16:51 怪怪 阅读(3133) | 评论 (29)编辑

对Singleton的实现方法做一个总结

     摘要: 说说Singleton的三种实现外加一个变种和一些细节。 还有什么没提到的, 大家也来讨论下~  阅读全文

posted @ 2008-05-10 02:02 怪怪 阅读(4170) | 评论 (27)编辑

不错不错

刚才上了好久不看的某站上瞅了两眼, 居然不少人开始认为这么多年来折腾这么多“大词”是缘木求鱼了。 也有人有胆量说最理想的编程方式就是在“php里一顿乱写”了, 更有人说绕着几道弯弄来弄去, 不过是“在数据库里读读写写”。

有救了。

Update:
顺便记录俩链接, 更准确的说是记录俩词, wiki上的文章不会学到什么, 不过相关词汇就全在哪里了, 未来找真正有用的东西的时候, 记不住的英文单词可以先到这些文章里找。

“突现论”在Wiki上的说明, 个人认为这门学说在很多问题上有点胡扯, 至少国内这方面某学者的著作有点胡扯。 不过具体到某一个特别现象,可能它倒是一个不错的解释工具。 比如自组织的一个实例, WWW, 也许可以用这方面的理论来思考一下。 问题是, 如何得到那个什么边界呢?
http://en.wikipedia.org/wiki/Emergence

这个, 和我最近的一些思路有关, 不知道怎么翻译? 嗯上面提到的某站,在这些方面倒能起到一个不错的提醒作用,毕竟国内也没几个集中讨论FP的地方了,虽然我的思路和FP没那么紧密的关系, 但是却可以受到FP的启发。
http://en.wikipedia.org/wiki/Continuation
http://en.wikipedia.org/wiki/Monads_in_functional_programming
http://en.wikipedia.org/wiki/Category_theory

posted @ 2008-05-08 07:23 怪怪 阅读(1004) | 评论 (3)编辑

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

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


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


另外, 那些对流行不感冒的兄弟, 也不用觉得自己太落后了, 至少肯定比明星梯队权威的人和你一样土; 问题的关键是写出像样的软件, 不是么?  阅读全文

posted @ 2008-04-29 14:37 怪怪 阅读(4318) | 评论 (36)编辑

闲言碎语

     摘要: 底部含有令人不适的内容, 请酌情观看。  阅读全文

posted @ 2008-04-21 16:34 怪怪 阅读(1876) | 评论 (12)编辑

Utility Wish List

最近想写几个小软件, 不过最近估计没啥时间, 在这里记录一下,以后一个一个完成。

谁要是感兴趣也可以共同参与进来, 一般来说除非特别明确的基于.NET平台的任务, 否则只使用C++。

初步定为开源的, 谁要是有在国外卖共享软件的经验, 也可以合作, 但最好可以保留有开源版本的。

1. 一个编辑照片的小软件, 原来给别人开发过一个, 但是有针对性, 而且代码不小心让我全弄丢了。 现在DC这么普及, 这种软件需求量有一些, 看国内一些开发者也在国外卖, 心里有点痒痒呵呵。 说白了, 就是把一些成熟算法打包, 一键式的完成大型软件得好多步骤的特殊目的的应用。 可能描述的有点不详细, 不是那种只有点增量变暗什么的软件, 而是可以变形(拉伸放大局部什么的), 去脏东西(电线杆什么的), 弄完图片一般人看不出来改过那种东西。

2. 一个简单的批量转换编码的软件。 现在用英文系统, 国内很多下载回来的文件都是GB2312的, 搞起来很麻烦。 这个最容易写, 有空顺手就给弄了。 最终就是右键单击, 然后选转换, over。

3. 一个虚拟驱动器和上面文件的小软件, 需求是这样: 比如现在网上下回来的高清TS都是好几个文件, 如果合并成一个, 这个合并过程又慢又需要很大硬盘空间; 不合并播放时切换文件太慢了。 让用户直接选几个文件, 加入虚拟驱动器, 就直接被虚拟成一个文件。 使用这个文件时, 比如播放, 由这个虚拟驱动器处理并转发。 这样对播放器来说,就是平滑的一个文件了。 这个有点难度, 不过我稍微调查了一下,还是有比较清晰的路子的; 最重要的可以熟悉一些平常干高阶编程不会了解的东西。

暂时就是这些吧..

posted @ 2008-04-15 11:16 怪怪 阅读(1667) | 评论 (9)编辑

随便说两句: 表设计兼一些设计分析的讨论

一个兄弟的问题:

1. 比方说有一个学生选课系统,设计老师,学生和课程等实体,是不是为了扩展或者说为了灵活性亦或为了更OO应当在实际的应用中加上person这个基类? 
2.再有比方说老师有教授和讲师,他们有各自不同的属性,如果不考虑数据的持久化,那么这个好像很好设计,但涉及到保存到数据库的时候,好像就很难处理了,在现实中我们应该不会有教授表老师表和讲师表,也许只有一个老师表,而会出现标志位的字段判断是否是讲师,是否是教授,但如果这样一个类对应一个数据库表应该是不错的选择, 这样的话,实体类就应当有一个老师类就可以了,教授类和讲师类就没了存在的必要,那么OO继承的优势何在?对于这样的问题解决方法是什么呢?


关于建表和对象继承:

首先, 我觉得如果你对面向对象设计的信息系统感兴趣, 可以看看Martin Fowler的《企业应用架构模式》。简单的说两句, 对于一个继承体系, 至少有三种建立关系模型的方式:

1. 一个老师表, 但是这个老师表, 同时有字段对应教授和讲师的属性, 一个教授的行, 其讲师的字段是空的, 一个讲师的行, 其教师特有的字段是空的。 对于很多现代数据库来说, 其冗余的Cell是不会占用存储空间的。

2. 假设没有老师这一具体职位(也就是说老师是抽象的基类),一个讲师表, 一个教授表, 这两个表具有一些相同的字段, 既教授和讲师共同具有的属于老师的特性的字段。

3. 有老师表, 讲师表, 和教授表三个表。 讲师表仅存储讲师的特性, 教授表仅存储教授的特性。 继承体系可能是这两种(讲师<- 老师 -> 教授),或(老师->讲师->教授), 但无论是哪种, 子类通过父类的ID, 和父类表向链接。 比如, 无论多了一个教授, 还是一个讲师, 老师表里都会增加一条老师记录, 如果是讲师, 同时在讲师表里插入讲师特有的信息, 如果是教授, 则同时在教授表里插入教授特有的信息。

所以, 对于一个继承体系来讲, 不见得在现实里只有一个表。 另外一点, 我个人认为, 这些不同的表的划分方式, 其实即使没有面向对象设计, 也是合理的, 同时自有其判断依据: 比如方式3, 有些场景, 我们仅仅需要老师的那些特性, 所以仅存取老师表即可; 有时候我们可能仅处理教授的特性, 而那些作为老师的共同特性反而不关心。 一旦我们关心全部特性, 我们可以将表连接起来。

以上三种方式, 都有一个前提, 既讲师和教授, 都有比起其父类, 更多的特性。 如果讲师和教授, 仅仅是身份不同, 像你说的, 最多有一个标志为标识其身份,我们不谈面向对象, 就谈对这件事的认识。

在现实生活中, 讲师和教授也许是有很多不同点, 以至于我们必须明确的分割这两种身份。 但是我们就我们所处理的任务的角度, 他们或许没什么不同: 系统内部只关心他们作为老师的一些特性; 而一些差异, 则仅仅是是一个子特性, 没有必要甚至不能够,上升到让这两种身份在*任务的视角上*产生真正的差异。

比如: 我们给不同身份的人发不同的工资。 这些仅仅是我们根据特性展开的, 其具体内容属于另一范畴的东西, 对于老师这一个概念来说, 身份只是一个很普通的标志, 就好比他是男还是女一样。 因为大多数关心的主要任务和这个属性关系不大, 所以就不会在系统内部设立两个不同的概念。 比如男的上男厕所, 女的上女厕所, 这是一个额外的规矩, 是在与人这个概念关系不大的其它部分进行的; 但是如果我们任务关心的问题, 就是女人和男人的差别, 情况则不同了。 比如女人和男人的体貌、 行为、 性格, 这些特点如果是我们要处理的, 很显然, 我们应该明确划分这两个概念。 从面向对象、特别是继承的观点来看, 我们需要至少两个对象; 当我们有时候同时关心男女共同为人的特点时, 我们还需要一个叫做“人”的基类对象。

在建表时, 也就会产生我上面所说的三种方式的不同差异。 至于三种方式的优劣, 暂时不能逐一展开, 不过Fowler那本书里都有提到; 不过读哪本书时, 可千万别当成什么金科玉律, 肺炎的种类很多, 不是吃茴香都能治的。

闲谈:

不过我们至少可以看出, 我们如何建表, 如何找到合适的模型, 并非是照搬现实生活里存在的概念的; 而是从我们的任务的视角上看过去, 存在哪些概念。 后者的判断, 在于我们关心些什么, 关心的这些内容, 造成了哪些程度上的不同, 有很大不同的时候, 我们需要不同的表达, 没有不同时, 我们就采用统一的表达。 而类设计和表设计, 只是我们表达的体现而已。  那么, 你所面对的问题, 从各方面来看, 需要几种表达方式才能完善呢?

同时, 我们在这时候, 不要过多的去考虑全局到具体, 而是把问题割裂开。 这个事情和谈恋爱正好相反,粘在一起的东西, 扯开比较费劲; 而把东西粘起来, 则相对容易。 这是因为我们人脑同一时间可以理清的东西有限。 所以我们要明确的认识到, 哪些东西可以规划到“男人上男厕所, 女人上女厕所”这样的外部规则, 哪些东西满足“男人和女人不同的特征”。 如果一时不容易分清, 至少我们在信息的量上可以做把握(不过这样把握的方式其实不是实质性的, 随着理解的深入, 就要放弃了), 后者往往涉及到一系列信息, 而前者中“男”“女”仅仅是一个用于填入规则的标志。

当然, 我们设计了一个表, 其中有一个字段存储“男”、“女”, 进行面向对象的设计的时候, 我们照样可以弄出一大堆类, 继承人这个类。 当我们调用, 人.上厕所()时, 就各去各的厕所了。 面向对象一般鼓励以这样的方式, 去给出统一的接口(比如这个例子里“人”)。 其优势在于, 当我们多出其它性别时, 比如“半男半女”、“不男不女”, 那些调用“人.上厕所()”的代码, 全都无需改变。

这里有一个假设, 在于“人”这个接口, 比如具有一些属性, 具有一个“上厕所”的方法, 这个接口是稳定的, 不会改变的。 当我们在进行设计时, 要衡量这个假设是不是成立的。 比如上厕所这个行为, 有可能在未来变化为“上厕所(带手纸)”, “上厕所(没带纸)”, 这样一个接口的变动。 很多面向对象设计只所以问题连连, 就在于做出了时效性太强的假设。

为什么这么说呢? 因为接口是有很大概率会变化的, 其区别仅仅是一个月之内就变, 还是这个系统用了3年才变。接口一旦发生变动, 我们往往就要为当初获得的好处埋单了。   所以如何设计, 有时候不是一个绝对化的问题, 而是一个想办法付出最小代价的问题。

对于上厕所, 我们可以统一的把上厕所的具体问题外包出去, 比如针对各种情况可能采取的各种方式, 这样我们就产生一个“上厕所的办法”这样一个外部概念。 我们可以想像, 当一个人脑子里有这个概念的时候(“人”这个类别的对象持有某一“上厕所策略”), 就可以根据判断“我是女的, 我上女厕”、“我没带纸、找张报纸”进行行为, 你可以说这些是这女的想的, 但是你也可以认为这些仅仅是外部规则, 这女的只是按照规则机械的行动而已; 这后一种看法, 实际上使得我们容易在计算机上设计。

这时候, 我们无需使用继承的体系, 而是采用“人.上厕所(策略)”这样的接口, 那么如果我们所关心的“男”、“女”, 和带纸没带纸一样, 仅仅是上厕所策略用以判断的素材而已; 这样, 我们就不需要男人类和女人类了。

从以上例子来看, 类的设计和表的设计, 不是说一定要有必然的联系。 因为既然我们写了非存取的代码, 就说明我们除了可以记录下来的特征, 还关心其它的非可固化性质的行为, 那么我们如何设计类、 对象, 则必须从这些行为以及系统中各个对象交互的视角上出发, 而不是考虑我们的表如何设计的。 注意, 这不是说我赞成以实体类去设计表, 关系模型关心和表现的是事情的另一个侧面, 所以设计表恰恰不能从对象设计倒回去。 它们之间应该是正交的, 不要存在一个依赖另外一个这样的耦合。 如何让他们兼容, 需要且应该做额外的工作。

当上面的例子简化到一定地步, 比如 if(男) ... else ...时, 我们也不需要什么策略的对象或者类, 有一些用于体现策略脚本处理即可。 到了这个地步, 我们也许一个实体类都不需要有。 我们就简单的把系统看作根据具体情况作出判断和处理的策略系统就可以了, 这时候我们需要的仅仅是信息的载体, 这就是为什么我经常会说, 当产生了贫血对象后, 我们要考虑的不是把它变复杂, 而是看看能不能把它从系统中抹去的原因。 很多时候, 贫血类比起一个通用的信息载体, 除了字段和属性强类型的好处, 仅仅发挥一个自身标识的作用; 但是当我们调用“人能做的事情静态帮助类.上厕所(信息载体)”的时候, 实际上我们已经隐式的传递了这个标识; 我们也可以设置一些具体的手法, 保证安全。

总结:

最后, 我们再来看看这些区别, 强化一下印象:

1. “人能做的事情.上厕所(信息载体)”、“人.上厕所()”和“人.上厕所(策略)”之间如何取舍, 在于复杂度, 复杂度上升到一定程度, 我们要采取后者; 这是为了避免前者“上厕所”这一Rotine其内部复杂度上升的太高, 或者被频繁修改。 另外一个更明确的判断点在于, 人是否带有可变化的状态; 上厕所这件事是否有很多的方式。

2. 假设我们采取了含有“人”这一样一个概念的具体表达的设计, 人这个接口如何保持稳定是我们要注意的。 比如“上厕所”这一行为隐含的变化, 或者又增加“吃饭”等行为, 都属于接口的不稳定, 如果这种不稳定在短期内就会出现, 我们应该把行为和规则外包给其它概念, 而不是让它们依附在人之上。 如果我们一出生就是狼孩, 本来我们也不会具有这些概念所指的行为; 并不是说“主语.谓语”, 这样的设计方式就是合理的。

3. 我们是否需要“男人”、“女人” 或者 “讲师”、 “教授” 这样的继承体系, 可以这样判断: 必须共性大、同时差异也大。 组合比继承好, 这是从95年《设计模式》以后被大家广泛接受的原则。 很显然, 共性和差异同时非常大的情况不是特别多见。 也许我们平时见惯了我们的aspx页面继承于Page, Page又继承于TemplateControl和Control。 且不说合理与否, 这并不能说明需要继承的情况很多。 因为这样一个继承, 使用了10000遍, 它其实还是一个继承。

4. 表设计和对象设计是两码事, 要按照各自的特点来做; 同时追求两边的合理性, 要付出的代价就是多做中间工作, 这些上面说的比较详细, 就不多说了。唯一可以说的是, 在成本上考虑, 我们要做好折中的选择。 更多的则是, 无论哪个设计, 无论什么设计方法, 我们别想太多, 更多的要找出我们关心的全部内容, 而不要把在现实生活中的知识带入过多; 因为对我们要解决的问题所在视角, 这些知识可能就成了不必要的偏见, 或者至少像用大学物理解释初中物理题。

这些问题其实在学习面向对象以后, 做类似的信息管理时, 非常普遍。 我想你先问问自己, 你自己想采用什么样的设计呢? 其次, 看看自己能不能找到这种设计的扩展或灵活性的好处。很多时候, 我感觉咱们想面向对象的冲动, 是因为不面向对象, 好像就不是一个设计, 简陋了些。 首先要克服这个心理。 如果找不到一个设计的好处, 而非要面向对象的话,即使存在一些好处, 也不是我们可以掌握的; 如果反而添了不少麻烦, 这些麻烦也不容易被找到。

总而言之, 我觉得, 不求巧, 但求拙, 不给自己的思路下套子, 不引入过多的杂念, 是设计的一些好的准则。

posted @ 2008-04-13 22:33 怪怪 阅读(3934) | 评论 (34)编辑

也论标准: 统一是啥好事情?

要说标准, 尤其最近的讨论都说到9X年了, 当年最不标准的似乎是Netscape, IE才是标准的先行者。那会儿这组织那机构的都干嘛去了?其实真正不作为的恰恰是其他人, 让Microsoft一统江湖了, 却又穷则生变, 开始知道应该发挥作用了。

另外如果世界上只有一种标准,而这种标准就是微软的,难道微软就真不会进步了吗? 不出新产品, 怎么挣钱? 不过是因为重心的转移制造了一个机会, 让一些“正义者”又回到了舞台上罢了。

要说Microsoft没错, 一个产品熬6年也确实真够可以的....,不过这种错, 充其量只是公司策略上的失误; 如果Netscape还在, 大家就更要骂娘了。 何况IE6的统治期虽然有种种不如意, 但是很多Web开发人员得到了一个相对平静的环境得以成长。

这就好比Windows 3.1 - Windows 9X再烂, 还是在90年代提供了一个相对稳定的环境, 培养了大批程序员。 如果Linux、UNIX、MacOS、OS/2那会儿全都活得生龙活虎, IT业进步是更快还是更慢可真不一定。 这叫什么来着? 原始积累的过程, 不过积累的是从业人员罢了。

现在Microsoft开始出让市场了(当然不是他大公无私),如果一个公司自己的错误, 要为全世界Web开发者的苦附上责任,那么考虑到如上这些,我们是不是应该反过来感谢微软呢?

我自己不太喜欢考虑这种问题, 而且说实话, 我不是一个纯粹的Web Developer, 但是我认为这对Web Developer也不是啥坏事。

你们想, 如果IE 6/IE 7/IE 8/FF/Safari/Opera/KHTML(靠好长的列表)平均分配名额, 就需要更多的技巧, 也就是说, 多了一种工作或工作量变大了, 相对掌握这些技巧的人,工资或者工作机会也更多了。

最好将来SilverLight/Flash/增强版SVG+JS也三分天下,接着微软原来的VML小组也复出, 干脆PNG文件也变成可编程的。 然后Google也出自己的东西, Sun的Applet东山再起。 一定要保证用户的机器有这个就没那个, 有那个没这个,最好和3721他们一样,互相卸载着玩。

嗯不错, 大把的银子啊, 向开发者们砸过来吧~

我这是真心的说, 一点反讽的意思都没有。 毕竟大多数人都在做基于这样那样产品(不仅仅是Web领域)的技巧性的工作, 并靠这些东西活命呢。

统一呢? 最终节约的是商业组织的成本而已,真的就让Web Developer少受痛苦吗? 不知道肚子饿苦不苦呢。 无论什么技术,发展的越慢,对我们这代开发者中的绝大多数来说, 技术生命就更长。

让百家争鸣, 各有个的标准来的猛烈些吧~~。

posted @ 2008-04-09 18:47 怪怪 阅读(3265) | 评论 (44)编辑

我终于有个偶像了

说实话, 我不关心, 也不喜欢政治, 对体育也没啥兴趣。 虽然我佩服Carmack, 佩服Gates, 佩服老毛, 佩服爱因斯坦, 但我没有偶像。就像大家看到的一样, 在我这里只有质疑。

 不过今天不同了,我终于有个偶像了。其实这样的偶像, 应该还有很多; 只是只有他/她们出现在公众视野, 才能被大家所知。 不是因为她为谁做了什么, 只为一个人忠于自己的梦想, 忠于自己的职责,敢于笑对任何困难的精神。









=======================================================

(转)央视境外传递火炬手接近尾声 轮椅剑客金晶脱颖而出
http://sports.sina.com.cn 2007年11月26日04:30 新闻晨报    □晨报记者王治明
  
经过四个多月的选拔,先后有6位出众的市民,在联想和《新闻晨报》共同搭建的选拔平台上脱颖而出,并在央视“你就是火炬手”的节目中表现优异,从而 成为联想奥运提名火炬手。他们是在成千上万报名参加火炬手选拔的普通人中的佼佼者,他们身上所折射出的“具有不断探索、超越的奥林匹克精神”,让他们成为 了平民“明星”。而金晶,则是提名火炬手中的幸运儿,她获得了即将远赴巴黎传递圣火的机会。对能去法国传递圣火,金晶非常高兴:“目前我还是队友的陪练, 如果能到巴黎传递圣火,想联系我们法国轮椅击剑队的队友,和他们碰个面。”
  
获选感言只要心里有阳光,眼睛里就都是温暖
  
真正成为火炬手,要等12月底奥组委正式盖章才能算呢,所以我的心情还没有很激动吧。但是,我被选上了,我真的很开心,真的,让我感到了很久不曾有 的感动,别人对你的认可和关爱,那么多人对你的呵护,让我知道了这么多年的坚持没有错,我也会带着所有人的期望走下去,带着我的勇气、带着我的微笑、带着 我的快乐,让所有的人知道:真诚的微笑可以温暖任何一颗悲伤的心,坚持自己的信念,一定可以感染更多的人。让每一天的阳光都很灿烂,让每一天的生活都过得 快乐,让身边每一个人的心都是温暖的。
  
当我拄着拐杖支撑起一条腿走在路上的时候,曾不只一次碰到过有些家长说自己的孩子和我 一样,但是不肯出门、不肯见人,他们希望我留下联系电话帮着劝导,可惜的是,都没有打过来。我觉得有时候仅仅靠个人的力量是很困难的。的确,走在路上,我 也能感觉到身边的目光,相信大部分人的眼光并不是恶意的,有部分佩服、有部分好奇、有部分怜惜,其实就看你自己是怎么看的。这次在火炬手境外选拔的时候, 说过的话中令我自己印象最深就是:“只要心里有阳光,眼睛里就都是温暖,这就是微笑的力量。”
  
我参加火炬手的选拔,也是希望能给一部分不如意的人一些鼓励,在“我想、我做、我超越”精神的感召下,希望火炬能让我心中奔跑的火种再次熊熊燃烧,希望举着“祥云”,超越我的人生,也鼓舞更多人!
  
参选心情是圆梦也是为了给更多人带去希望
  
又一次北京之行结束了。虽然这次是在提名火炬手中选拔境外火炬手,但是却明显感到了气氛和上次选拔的不同,可能是肩负的责任不同吧。晚上最后一场录 制好之后在聚餐时,几个导演都哭了,从这档节目中收获了感动,可同时也留下了遗憾。有导演说,当她看到那些选手在台上紧张得都说不出话的时候,真的很难 过,不知道自己做的是对还是错。给普通人一个展示自己奥运梦想的舞台,有辉煌也有压力,这个同奥林匹克的竞技场也有雷同之处。
  
许多选手明显没有上次国内竞选时那么自如了,背负着城市和单位甚至是一个群体的期待,每个人都很优秀,都有自己感人的故事和奥运情结,可是这毕竟是选 拔,总有人晋级、有人被淘汰。我们中也有人是带着希望来参选,希望当选火炬手能有更多的机会宣传我国的历史文化、能让更多的人传递爱心、让更多人关心爱护 残疾人和弱势群体等等。这不仅仅是圆一个奥运的梦想,也是给更多人带来鼓励和希望。
  
对轮椅与剑的独白我知道,我并不是一个人在战斗
  
记得2004年奥运会没有能去,除了失望真的还有彻骨的痛,这种痛苦绝对不亚于失恋,当时看着曾经陪我走过两年的剑不禁哭了,觉得自己对不起它们,陪我打了那么多场比赛,因为主人的不争气,却没有能够去奥运赛场一展身手。
  
看着我的比赛轮椅,心里不禁又一痛,7年了,跟了我7年,摔过、撞过,就像自己最亲的战友,默默无闻地支持着我。现在这辆轮椅已经很破旧了,去年国 家队换轮椅的时候,我没有用新发的,还是用我这辆第一次去国际比赛就用的紫色轮椅,因为它是朋友、是兄弟、是战友,虽然我没有出息,从来没有带它登上冠军 的领奖台,也没有和它一起走在奥运赛场的赛道上,但是仍然不离不弃。现在它已经很旧,甚至可以说很破了,但是依然结实,就像我一样,不知道我们还能在一起 奋战多久,但是我知道并不是我一个人在战斗,随着进攻后退的摇动,是我和轮椅一起作战,是我们共同的战役……
  
谢谢你,我的轮椅,只要我还在训练一天就不会抛下你,因为你是我最亲密的伙伴!

========================================================

(转某新闻段落)新华社巴黎4月7日奥运专电(记者张荣锋、马邦杰)

从金京懂事起,奔跑就成为了生命里的旋律,从卧室跑入客厅、从楼上跑向楼下、从教室跑到操场。对金京来说,奔跑就是世界上最幸福的事。可九岁那年,命运和 她开了一个大玩笑。恶性肿瘤——横纹肌肉瘤,判定了这个小女孩的命运,奔跑永远只能是梦想了。为了保住生命,她只能接受截肢手术。
    
失去了一条腿,并没有让金京失去生存的信心。虽然以后陪伴着她的只是轮椅和拐杖,但是对奔跑的渴望始终是她心中燃烧的火种。2001年7月13日,也就是北京申奥成功那天,她加入上海轮椅击剑队,当然还有个原因就是喜欢佐罗。
    
对她来说,参加轮椅击剑遇到了很多常人难以想象得困难——金京的身体有些瘦弱,个子不高,这样一来就意味着她的手臂相对比较短,力量不足,高位截肢 也使她在防守上有着一定的劣势。然而这一切都不能阻挡她,坚强意志和奥运精神支持着她刻苦训练。很快,金京在属于她的赛场上取得了优异成绩,几年内拿到了 多个世界级比赛奖牌。通过刻苦训练,金京不但在击剑赛场上取得了优异的成绩,还在电视节目“舞林大会”上有了几近完美的表现。
    
阴错阳差,金京没能参加雅典残奥会。随着年龄的增长,她也将无缘北京奥运会。正当她为无法参加奥运会感到遗憾的时候,“你就是联想奥运火炬手”的大字印入她的眼帘,她的毅力让她赢得了自己的奥运空间。
    
对于未来,她充满信心。“一路走来,受到了很多人的肯定,我对自己的要求要更高。我能够成为一名奥运火炬手,证明残疾人能做到的事情有很多,”金京满怀期待地憧憬着未来之路。
    
金京最喜欢的一句话是《乱世佳人》的收尾句——“还有明天”

posted @ 2008-04-09 04:36 怪怪 阅读(127) | 评论 (7)编辑

是他妈傻子写的么?

最近帮一个朋友做些Community Server改造的工作, 说实话, 我早就对这玩意深恶痛绝了, 也许是太长时间不干, 恶心劲儿过去了, 也就勉强答应了。

今天看了一段代码,我就他妈那一个操, 这是他妈傻子写的么? 傻子能写出二十来万行代码外加几十万行杂七杂八的aspx以及配置文件, 也真不容易。

想想这玩意儿居然也卖的出去, 卖的还挺贵, 我真得琢磨琢磨了。 说实在的, 虽然Discuz大多数地方和丫估计在一个水平线上, 有些涉及到认识方面的水平还稍低(虽然Community Server就一大杂烩), 不过Discuz绝不会有这么傻的开发人员。

那些Community Server对一些问题的正确认识(其实也就那几点), 也绝非因为他们脑子更好使或者知识更多, 只不过正好处在IT行业的风口浪尖, 受外部环境影响, 不小心就按照正确的方式理解了罢了。问题是理解对不代表用的好,所以CS的维护和二次开发成本居然会那么高。

微软居然也敢用它的产品,这说明什么?美国人的脑子怎么长的真是值得研究一下; 顺便又想起前阵子美国程序员效率是中国程序员10倍的××言论了。严重支持Discuz好好完善, 进军美国。

说实话, 这世界上烂货很多, 水平高的组织很少, 好多兄弟就是不相信这一点, 不相信自己绝对能超过这帮丫的, 于是一辈子就是一打工仔。 也许只有傻子才能义无反顾的拿着一把刷子就上了。

该聪明的地方聪明,该傻的地方看来还真得傻点。

Update 自回复:

更早的版本,2.1 SP3, 不过除非2007和2008是完全重写的, 否则我敢打包票很多问题还在。

比如: Pemission.Administer, 如果你是一个Gallery的Onwer你就有这个权限,如果你是Weblog的,却不能保证; 当然这是从数据持久上就出问题了,问题是初始化Gallery和Weblog这个数据的SQL就肩并肩挨在一起, 怎么也看见了。在整个项目里查, 它没有用Administer去进行Blog的权限检查, 但是Gallery和其它一些ApplicationType却用了,也就是说这是一个全面的不统一, 而不是一个失误。

这样的问题, 也不仅仅这一处, 要真仔细挑, 估计且得挑一阵子挑不完。不一致性隐藏在伪装一致性之中, 比重复代码还烂。 这些并不是那种普通的缺陷,而是说明他们的开发人员缺乏很多一直被倡导的优良理念。

然后你看看PostCategory的Sort,比如NameDesc和Name, 他们自己写了一个继承自DropDown的控件, 里面SortOrder和SortBy基于Sort和SortBy的enum.ToString()相加去DropDownList.Items查找,这一块实现的效率、优雅咱们都不谈, 居然会加出NameDesc_Descending这样的东西,然后根本查找不到。

可能有些人觉得写出这样的代码只不过是一时失误(比如程序员累了烦躁了什么的), 其实根本不是。 这就是典型的不合格程序员的不合格设计思路,导致这种问题频出, 他们所谓的“支持资源太多”, 完全是因为他们自己弄得烂,导致越扩展,维护成本越高昂。

确实,他们对ASP.NET的机制认识很好, 非常好, 相当的好。 但是没有更基本的指导思想, 把握不住正确的视角, 最后就只会把正确的认识用到错误的地方。比如他们的Theme系统充分的利用的ASP.NET WebForm的特点,可是仔细摸一下, 脉络却非常不清楚, 各种不同层面的行为、概念,全都交织在一起。

再说流程, 由于没有建立统一的基于过程和请求的上下文模型而仅仅搞一个CSContext这样的当前请求全局对象, 导致不同控件对多个相同的Routine的多次*无必要*的重复。而CSContext的设计也是漏洞百出: 除了少数几个基本的属性,根本无法判断什么属性在什么时候其值是健康的。

再说所谓的大客户,大客户的Section应该很多吧? 微软早在2.1之前就用他们的程序了, 你看看Section的获取这一块写的, 获取全部的Section然后再foreach看看哪个符合条件。 大客户有钱买硬件, 也不能这么浪费啊。

硬编码根本不是关键问题, 各种相似子程序的重复太厉害了; 比如Gallery和Weblog很多地方代码除了类型变了,细节稍微有点不同, 总体来说就没什么变化,基本就是复制粘贴的结果。 而好不容易复用的东西, 又经常产生了隐蔽的非正交,导致问题很多。如果不是一处两处, 我觉得就很说明问题了, 其开发者根本就不知道如何就这种相似进行合理的设计(虽然前瞻性不靠谱, 但是也不能一点这种能力都没有吧), 只能等不堪重负,再根据现有情况重构。

如果整理一下的话,功能不变的前提下,我判断它的代码至少可以精简到一半(说白了就是拿现在的版本当个素材库整个重写)。 如果没有这种大动作,我敢打包票, 无论他们重构出什么东西, 很快就又会产生新的问题。 这根本不是代码的问题, 而是人的水平问题; 而且他们的水平长进速度也是相当的慢。

比如最上面提到的Permission的问题, 可以想象是因为缺乏统一性而不愿意轻易动以前的设定, 问题是个现代程序员都知道, 对这种问题姑息下去, 最终会越来越糟; 可是只要程序还能转, 就克服不了心里的阻力去统一一下。 CS升级这么多年了,里面各个方面到处都是这种妥协, 都成了习惯了, 这样的开发和维护过程最终必定积重难返。

这个产品(如果2007/2008不是推倒重来的), 除了你说的确实体现了他们对ASP.NET的认识, 从头到尾是不折不扣的垃圾。 以我现在看问题的方式,如果让我选择, 我宁可选一个ASP式的东西,也不愿意用它; 可惜微软平台上, 如果二次开发, 就他功能最全了。

说实在的, 要是我这朋友有足够的资金和人力, 我绝不会让他基于Community Server做二次开发。

posted @ 2008-04-08 03:56 怪怪 阅读(325) | 评论 (13)编辑

闲话: 恭喜园子里的MVP一下, 同时问所有奋斗在技术领域的兄弟过节好~

     摘要: 恭喜一下园子里所有的新老MVP, 我觉得MVP在很多方面还是很有说服力的; 有些人心里不平衡, 请想想你为任何组织或者别人做了什么。

同时借着清明节,向所有奋斗在第一线上的兄弟致敬。  阅读全文

posted @ 2008-04-04 01:58 怪怪 阅读(1775) | 评论 (15)编辑

笔记

刚才无聊,翻一原来的哲学小册子, 看到亚里士多德学派的哲学思想时,突然感觉眼前一亮。 和软件构建的实质感觉上比较接近,这个得好好琢磨琢磨。 嗯, 出于不同的角色, 看相同的东西, 也会有不同的收获。

Update:
其实关键是材料因和形式因, 很多人包括一些曾经的经典观念, 都掐的太死。 什么是材料? 数据是, 具体算法逐渐的也被认可是(比如以策略或者插件的形式), 其实经常变一个角度, 曾经的形式, 就变为了材料, 我们可以从更高的层面去组织它们。 现有的一些经典学说, 包括面向对象, 还有一个问题就是混淆材料和形式。 这个暂时不细说了。

posted @ 2008-03-30 10:50 怪怪 阅读(272) | 评论 (4)编辑

文章收录

有些点稍微有点偏激和不客观,不过很多地方还是命中要害的。
http://www.inter-sections.net/2007/11/13/how-to-recognise-a-good-programmer/

InfoQ上的文章, 按照这篇文章看, 国内社区就基本没有“精通”和“专家”级别的程序员; 虽然文章内容还是有些机械, 少了“半精通”,“半专家”(非程度上的, 而是状态上的)这些, 而且我也不想得罪人, 但是说实话那个Dreyfus模型还是很有几分道理的。就是不知道为什么这种站点采用的文章中, 就是这种很纯洁的作品味儿都有点不对。
http://www.infoq.com/articles/better-best-practices
中文:http://www.infoq.com/cn/articles/better-best-practices


虽然跟不上他开阔的眼界,但是很多介绍的东西还是应该了解的, 就好象一个非常好的窗户,g9的博客。 说实话, pongba也经常玩些“虚的”,含金量也不低, 但是和g9还是很有区别的。 有些人哪怕他知道很多你不知道的, 你看半天也学不着什么, 直到你用到相关内容了, 才觉得是个挺好的参考; 有些人就不一样了, 就好象一个非常好的导游, 对读者娓娓而谈, 哪怕一些事情跟咱的任务一点关系没有, 看起来也很过瘾。
http://blog.csdn.net/g9yuayon


这是g9介绍的一篇文章, 据说里面提到什么什么程序, 80个人写都搞不定, 临到最后, 把这80个人都撤了, 换成一个人干, 交活了。 McConnell写的, 我没看。 既然这么有传奇性, 就保存一下吧。
http://forums.construx.com/blogs/stevemcc/archive/2008/03/27/productivity-variations-among-software-developers-and-teams-the-origin-of-quot-10x-quot.aspx

Windbg资源:
http://www.debuginfo.com/articles/easywindbg.html

posted @ 2008-03-26 09:25 怪怪 阅读(345) | 评论 (0)编辑

三问TDD: 单元测试总是好的吗?

     摘要: 有关测试“后行”也可以接受的说法,说明了一个事实:即使是最中坚的测试粉丝,也经常需要修正自我。很多理论抛出来之后,在现实面前,都不断的妥协。一些妥协到基本完善,一些妥协到基本完蛋。   阅读全文

posted @ 2008-03-16 02:36 怪怪 阅读(6524) | 评论 (42)编辑

再问TDD: 扩散角模型

     摘要: 用一个简单的模型, 来看一下TDD的适用性; 同时再讨论一下对人的要求。

  阅读全文

posted @ 2008-03-15 15:10 怪怪 阅读(1552) | 评论 (13)编辑

回帖整理: 关于TDD引发的流行方法的思考

     摘要: 讨论: 面对一波又一波的流行趋势, 国内典型的混乱组织和中小型组织, 应该如何做?  阅读全文

posted @ 2008-03-15 00:54 怪怪 阅读(1825) | 评论 (7)编辑

最近闲话比较多了, 应该消停点~

提醒一下自己, 该干活干活, 少那么多废话; 再不行就拔网线了。
多提醒一次, 少发表对谁都没有帮助的意见。

posted @ 2008-03-13 19:59 怪怪 阅读(717) | 评论 (10)编辑

什么是专业? 谁更专业?

     摘要: 这里有一个据说的但是真实性上还算有保障的例子,而且这样的例子在咱们身边也存在很多: 某测试大牛在微软做的非常好, 被Google挖走了;干了1年之后, 实在干不下去了, 于是离职。 别人问他怎么回事, 他说简而言之一句话: Google根本就不存在他能够发挥专长的环境。
  阅读全文

posted @ 2008-03-13 18:02 怪怪 阅读(7688) | 评论 (32)编辑

回帖整理: 关于面向对象与数据操作的集合贴

以后关于这个话题, 零碎但有些价值的讨论统一更新至此帖, 有一定内容了再定期整理。

原帖: 关于业务层代码的组织

回复:

你说的稍微有点简略,不过如果你指的业务操作是数据库相关操作的话:这个问题1年前干嘴仗的结果好像说的很清楚了。

CRUD这类操作不属于BL的范畴,应该放入边界对象里; 对象是否贫血, 要看对象是否真的存在自身的业务逻辑。那种认为相关数据操作应该在对象身上就更面向对象的说法,实际上是没真正学过这方面知识的人的一知半解。

不过大嘴Fowler的书里ActiveRecord等两个方式的一个表现出来的特征就是CRUD在对象上(有时通过基类搞定),这种设计很多时候也是行之有效的; 同时是不少ORM/半ORM工具箱所采取的做法之一(虽然我对ORM极端不感冒)。不过, ActiveRecord的实质还是处理行数据等操作,其对象形式只是一个伪装; 以我的观点,恰恰是不那么干净的设计,这样的对象干脆就叫混血对象吧。

另外, ActiveRecord...,我有时候真想不通能给咱带来什么好处。难道Object.Delete()打起字来比较爽? 所以我个人觉得你这种做法很不错, 只是我不喜欢代码生成的方式 :P

同时,我认为如果是彻底贫血的对象, 可以好好考察一下它是否真有必要以确定为某一具体型别的对象的面目出现; 而不是反过来对该型别的对象缺乏操作耿耿于怀, 恨不得把所有和它沾边的事情都交给它负责。

资料:
别在领域模型迷失了自己,在当前讨论的这个论题中,我们着重要把握的是找准“系统边界”; 比如,对于该文中的“域控制器”, 我们应结合上下文去体会其角色, 就不难理解设计对象时的要点了。

还有一些其他的素材,包括思归在一些主角的博客里的留言也很有画龙点睛的作用(以至于到现在还有印象),一时收集不全了,慢慢找吧。

posted @ 2008-03-12 06:14 怪怪 阅读(1372) | 评论 (16)编辑

胡言乱语一篇: 所谓面向对象与关系模型的矛盾

神秀身是菩提树,心为明镜台; 时时勤拂拭,勿使惹尘埃。

听起来很美,不是? 到今天大家还纯洁的相信Rows->Entities就是解决之道,代表了基于数据库的软件如何表现面向对象的精髓; 顽固而勤奋的寻找一个又一个的方案, 希望自己的设计水平能够一次又一次的进化,最终能够正确处理好两者之间的关系。不得不说一句,这种生硬的处理方式,要是能没矛盾,倒稀奇了。

DTO能够让IDE提供足够的信息, 能够让编译器做出适当的检查,可即使是Rich Object,在ORM负责的这一段,能发挥的真实作用也不过仅此而已. 到底有啥必要去ORM? 业务逻辑本身什么时候要求所有的数据都要变成对象了? 我们想清楚没有, 到底需要的是什么能力, 想要解决什么问题? 在进行手工的或者自动化的ORM的时候,我们到底是在寻求帮助,还是在添加障碍?

这么多年来,谁说这种方式不对,谁就被当菜鸟; 最后受益的真不知道是所谓的高手们呢,还是各种厂商。 C#这些语言中纯粹面向对象的部分, 不得不说,正在误入歧途。 制造一个麻烦,解决它,然后再制造一个。 也许这样,所有的厂商和程序员都有饭吃, 很好很强大。

即便是伟大的无与伦比的面向对象,要想不受束缚的去设计,就必须隔断数据库和业务逻辑的关系; 这不能是添加一个数据操作层或者ORM去隔断,当咱们这么做的时候,实际上恰恰是在建立一种强联系。 最可笑的是,哪怕最清晰明了的模型,也会变得复杂起来。看看CommunityServer这么一个Web系统几年来的所谓进化吧,里面的一个又一个的死对象不断的浮肿起来,带来了多少不必要的繁文缛节和沉重负担。

一个PetShop,作为一种展示无可厚非,可它又让多少人不得不在所谓的n层之间的接口上徒增烦恼呢?在我看来,什么狗屁解耦,整个PetShop,就是Linus说的围绕一堆“漂亮对象”建立起来的坚固堡垒,想要把箭楼换个位置? 除非你是秦始皇。 我一直反对Linus愤青式的言辞,但不得不说,是所有面向对象爱好者和一部分所谓“经典范例”,给了他们这些人口实。

真正的自由和解耦,是视角和思想上的分离: 我们写下的每一行代码,都应该只基于上下文相关的概念,而不是任何形式的接口。这样需要变动的,就只剩下接口与概念之间的适配物了; 同时我们获得的就是真正意义上接口的自由: 从数据库/表/字段这些接口的变化,到这些数据可以转化为的任意一种对象所体现的接口的变化。

在Linq大行其道的今天,这篇东西有点战斗檄文的意思,就不发首页了。我现在想法还很不成熟,但是深切感觉到这方面问题的兄弟们,如果你愿意了解我在这方面的想法,我一定想办法逐渐把它清晰化,一点一点的呈现出来。

六祖慧能菩提本无树, 明镜亦非台; 本来无一物, 何处惹尘埃?

posted @ 2008-03-10 17:03 怪怪 阅读(1673) | 评论 (7)编辑

业余程序员宣言: 我们就TM不专业了, 怎么了?

看园子里文章<<什么是专业的程序员>>有感, 故发此文. 首先要说明, 我不是一个专业的程序员, 如果你自认专业, 是大中型企业的精英份子; 或者你认为别人的个性与你的职业精神格格不入, 对企业和信息技术的发展毫无用处, 不妨现在点右上角的x.

另外说明一点, 原文中一些正确的观念, 也是我们应该思考的, 我只是针对一些有待商榷的观点进行讨论, 不代表全盘否定. 而且说实话, 我这篇文章里最刺耳的词汇也不是针对园子里的同志, 更不是针对上面引用的这篇文章的作者; 对号入座的工作, 交给每个读者去完成.

该文中提到:
引用专业的程序员必须:

a        专业的企业精神

b         编程很专业

c         做事很专业

不专业的程序员:

Ø         无企业精神

Ø         编程不专业

Ø         做事不专业


在这个对比中, 存在着严重的误导和偷换概念. 简单说来, 其中的a, b, c, 根本不是连带性的, 也不能够划等号, 甚至我们可以说, 这中间根本没有必然联系. 在这三点中, 充分的体现了大中型企业对各个层次员工的预期, 而不是结果. 在这种言论中, 我们不难看到对人的作为主体的差异性的极端忽视; 这才是导致失败的源泉.

问题一: 没有企业精神, 就等于编程不专业, 做事不专业吗?

既然原文和原文引用的某人的文章中提到西方的观念, 就让我们看看西方人的历史吧: 从最