怪怪 | Nothing, Everything

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

是他妈傻子写的么?

最近帮一个朋友做些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 on 2008-04-08 03:56 怪怪 阅读(349) 评论(13)  编辑 收藏

评论

#1楼    回复  引用  查看    

不知道你说提是2007还是2008,或者是更早的版本?

就我看来,他们的水平还是可以的。Chameleon很有创意的UI从Model“拉数据”,而且完全是从asp.net内置机制里做出来的。再联系到Asp.net Membership的发展过程(就我所知,好像就是CS启的头),我觉得他们对Asp.net,WebForms的理解还是相当深的。

问题当然也有,
1,没有想过把CS做成一个应用平台,让别人也可以轻松在CS基础上开发新的应用,并方便地与原有的缓存,评论,打分,搜索,TAG等等结合在一起。
2,对中文等不使用26个字母的语言支持太差。
3,太过重量级。
但事实是,在这个领域,CS已经是做得最好的了。不过他们的新市场策略是放弃中小企业及个人用户(有免费限功能但没有任何支持的版本),主攻高端,像微软Dell这样的大客户,因为“小客户带来的利润小而占用的支持资源太多”。

不知道你是看到哪些地方不爽,不妨交流一下:)
2008-04-08 05:12 | deerchao      

#2楼    回复  引用  查看    

当然,还有不少硬编码,得过且过的场景。没办法,商业公司永远有发布日期压着,没条件追求绝对的完美。
2008-04-08 05:20 | deerchao      

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

更早的版本,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做二次开发。
2008-04-08 09:32 | 怪怪      

#4楼    回复  引用  查看    

说实在的,我没用过这个。

怪怪莫生气,如果改造费劲就自己写个轻型应用啊,我们也可以瞻仰下。^^
2008-04-08 11:22 | 黑羽飘舞      

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

主要是现在人胃口太大了..., 什么博客相册论坛乱七八糟的什么都要, 一张嘴就是要做全功能的社区, 这也有用那也有用, 功能弱点还不行。

说实在的, 我打心眼里不认为他们这种理念会成功, 所以才让他们拿现有的东西改吧改吧,先试验一下。 不然把工作几年攒的那点钱搭进去也就够做个开发, 真不值。

根本上就是我现在对做大而全的社区应用一点不感冒, 还是自己有兴趣的事情重要一点; 否则也说不上什么轻型或者重型(我并不是嫌它重型, 重型和优良的设计也不是对立的), 怎么正确怎么来。

其实我也说不上对CS生气, 毕竟从头重构一遍, 工作量比瞎改改凑合事还是要大很多, 只是被搞烦了, 发发牢骚罢了。相反我还得感谢CS, 有这个心目中的Web应用大反派提醒, 做自己的东西时候, 很多陷阱就可以先绕过去了。
2008-04-08 11:42 | 怪怪      

#6楼    回复  引用  查看    

确实有些东西是由于事先没有一个统一的规划,而在开发过程中临时往里边塞的。

CSContext其实就是一个强类型化了的HttpContext而已,他们从一开始就并没有打算实现一个全新的机制在页面处理的整个流程中进行通信,于是就这么着了。当然后果就是哪些值在什么时候可用,什么时候不可用这个和WebForms的生命周期一样,显得极为复杂了。

但是为什么要用这么个Context来通信?难道不能每次需要一个值时即时计算吗?我觉得这个反应了他们的一个理念:缓存一切能缓存的东西。这个可能是过度设计,也可能是他们的大客户高PV量的实践中发现这么做最有利于性能。具体是什么原因,我就不得而知了。

说到缓存,这也解释了他们为什么采用“获取全部的Section然后再foreach看看哪个符合条件”这样的操作方式了,全部的Section肯定是要缓存起来的,在内存中进行比较判断相对而言还是轻量级的操作,需要的时间不会太多。当然比从一个Hash表里直接取还是要慢,但是可能他们觉得扔到Hash表里只利于一个一个地取出,不例于取出符合查询条件的一系列子项,为了灵活性,于是就统统foreach了,反正几百个循环个几百次也不会用多少时间。

代码重复这个问题在CS2008里依然存在。奇怪的是即使是有了基类,基类里定义的也只有接口,没有实现,几个子类里依然完全是类似甚至相同的逻辑。这个我就不明白了,怎么想也想不出原因,除非他们热爱abstract,憎恨virtual.

UI层的话,从07开始,使用了一个全新的引擎,非常灵活,这个还是很有创造力的。与常规的页面代码取出数据,扔到模板引擎里生成最终输出的过程相反,Chameleon里是直接从页面指出要显示哪些数据,以及如何格式化。而支撑这一点的是它的隐式数据源特性,就是说你把一个UserData控件放到一个PostData控件里头之后,UserData的默认数据源就是Post的发表用户,类似这样的东西。

其实,CS更多的是一个最终消费产品,而不是一个开发平台。如果不看代码里种种龌鹾的地方,仅从功能/性能而言,还是个过得去的产品。虽然像我们这样的开发者憎恨大而全,喜欢明确的需求,狭窄领域的创新应用,但是不可否认的是很多不做技术的人确实是更喜欢所有东西都包括了的恐龙级产品。你说他们的理念不会成功,可是他们已经有了微软,dell, 宝马等等相当多的大客户,大概是大家的着眼点不同吧。

我觉得有技术洁癖不是坏事,可是要不能在这个肮脏的世界里生存下去就不好了。说实话,有时我做的事也是一样每次都需要重新鼓足勇气才敢继续做下去。。。
2008-04-09 05:42 | deerchao      

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

Section的问题, 对forum当然没问题, 但是如果是50W上百万个博客呢?

他还号称针对Web farm, 可是它这么设计, 到时如何分割? 分割后又如何统一?

Context这一块, 谁都知道全局的危害。 可你说的次次计算, 对于他们来说不靠谱。 因为他们光看到了封装的优势, 什么都封装, 这导致一个页面相同的计算会重复很多次, 就像我上面说的, 即使是现在, 这个已经很夸张了, 如果Context上的东西也次次计算, 这东西就真没法要了。

其实你觉得不明白只是个借口, 大家心里都知道是咋回事, 只是既然曾经NB过,现在也拿它们做二次开发, 总希望能帮他们找个借口。 他们有强项, 但弱项很多也很明显。 我打算这个朋友以后一段时间以内, 不帮别人做类似的工作了。

我前年年末去年年初也设计了一个UI方面的东西(从架构-》引擎-》产品), 到现在还没有实现完, 我还是得专注自己的东西才行。 至少自己的东西, 不愉快的体验是自己带来的, 不会生第三方闷气。

微软啊什么的, 都是有明确需求的: 需要论坛, 需要博客,但他们不靠这些当卖点, 只是支撑自己的服务。 这和我这些朋友不同, 他们兴起创业的念头, 本来都是有特定的点的, 可是在过程中就一点一点的丧失了...

你提供的信息很关键, 我会去参考一下他们在UI方面的新东西有什么亮点值得我借鉴的 :),不过我有信心如果单从Web UI来讲, 我的理念绝对够强, 前提是我必须完成它。 没有进展的另一个原因是, 确实存在着一些现在谁也没解决,而且可能是解决不了的“肮脏”问题, 而我居然妄图先把它们想通, 然后一劳永逸。

勇气我还是有的, 忍受也是不得不去做的事情, 只是我希望能够把可以解决的范围最大化。 这一年多做了太多和自己真正想干的无关的事,现在我想好了, 就是没饭吃, 我也在所不惜。
2008-04-09 09:10 | 怪怪      

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

去看了一下你说的Chameleon, 说实在的, "朝三暮四"式的东西有点...

也许是我没细看,

<CSControl:UserData runat=”server” Property=”DisplayName” LinkTo=”Profile”>
<LeaderTemplate>
<div id=”UserArea”>
<h2 style=”color: #ff0000; font-size: 200%;”>
</LeaderTemplate>
<TrailerTemplate>
</h2>
</div>
</TrailerTemplate>
</CSControl:UserData>


<div id=”UserArea”>
<h2 style=”color: #ff0000; font-size: 200%;”>
<%= GetAccessingUser().DisplayName %>
</h2>
</div>

虽然看起来好似体现了不同的思路, 可实际上有何本质不同? 我觉得认为前者比后者帅, 虽然也有一定道理, 不过也有自欺欺人的一方面。 这和asp:Repeater代替<%= foreach%> 是有点不一样的, 不过我光咂叭出来一个味儿, 还不能细说其中奥妙。

我这人总是批判大于赞扬, 老兄应该熟悉我这个风格了, 不是说我不承认他的优点和进步(靠比以前是强太多了, 估计能少受很多苦), 继续去看了...

你平时用这玩意多吗?
2008-04-09 09:39 | 怪怪      

#9楼    回复  引用  查看    

@怪怪
呵呵,我平常用也得不多,但有时(大约每几个月一次吧)还是得添加点小功能,改点bug之类的。

他们的新UI层最关键的是自动的隐式数据源绑定,配上其它的一些基础设施可以基本消除.aspx.cs。这个是asp:Repeater甚至asp式的输出代码都不能相比的,关键在于其自适应性,要不也不叫变色龙(Chameleon)了,呵呵。

而没有了程序代码(.cs或内联的C#代码),美工学习掌握的可能性也就更大一些。
2008-04-09 10:10 | deerchao      

#10楼    回复  引用  查看    

微软啊什么的, 都是有明确需求的: 需要论坛, 需要博客,但他们不靠这些当卖点, 只是支撑自己的服务。 这和我这些朋友不同, 他们兴起创业的念头, 本来都是有特定的点的, 可是在过程中就一点一点的丧失了...
----------
是啊,不少非技术出身的做网站时很可能刚开始时想做某个特定的需求,然后一看这个软件能提供论坛博客,那个软件能提供相册小组,等等等等,结果到最后什么都想上。。
对某些搞技术的来说,眼看着一个单纯可爱的目标,变得浓装艳抹流俗于众确实是件痛苦的事。
2008-04-09 10:19 | deerchao      

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

@deerchao
呵呵, 我不是支持内联代码, 只是它们这种做法其实还是在穿新鞋,走老路; 我指的和Repeater不同是指在跨度上。

等我的方式抛出来, 你就知道我说的是啥了; 不过我可不是藏私, 而是那种小孩弄个好东西想瞒一阵子的感觉,叫卖关子吧 :P。

本来想你要是用CS多, 等我手头工作完了, 正好需要把一些已有应用整合进来做个演示。 这时候咱俩可以一起把CS里有用的东西整理出一个独立于界面的东西, 大家各取所需~
2008-04-09 11:14 | 怪怪      

#12楼    回复  引用  查看    

别提了,我就是看了些cs的介绍,被其技术所迷惑,06年搞了一下,搞 的我要死,真的不如我自己搞一个,如果和discuzNT比,我只能说CS很垃圾,UI方面极其不人性化,社区就是要拿来用的,cs那玩意基本上不能拿来用,改造相当困难,要不宝玉也不会重起炉灶搞他的OL了。
2008-04-09 19:19 | 偶卖糕的      

#13楼    回复  引用  查看    

假如说纯技术,CS不至于需要拿去和DISCUZ.net相比,假如说产品面,不多说什么,CS很糟糕。
2008-06-28 09:21 | 坏人      

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


相关链接: