Update:这篇比较老的一篇文章瞎补充了一些内容,比较混乱。此文和文后回复,请配合《我到底是在干嘛?》一起看,但不保证是说清楚了一些,还是更混乱了 :S。
对我讨论的这些话题,我的观点,明确成一句话来说:既然目前那么多现存编程范式中的种种原则、手法,都是针对*组织*这一问题的,那么我认为这恰好证明,些编程范式和其周边设施所提供的组织能力,就到了该大步伐革新的时候了;而且如果一种改良是通过损失另外一些特征得到的,我认为这种改良并不可取,仅仅是将问题转移到另一处罢了,而其根源则并没有得到消除。
今天我在这里说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平台上的语言目前就是这种状况, 我自己也是在鉴于现实原因没法换的境地)。
Update:在这篇文章里似乎只针对了静态OO不结合其它范式的情况下类型系统造成的麻烦,看起来统称为OO的本质缺陷似乎不妥。但实际上,避免了类型一棍子打死式的约束的、可以修改对象的语言只是把问题换了一个地方。它们的麻烦不同,但我初步认为,在那个模模糊糊的深层次上,根源是相同的。
我在上面推荐动态语言,只是在针对目标,问题仅仅存在在表达能力不足时的一个选择。而且是不是动态了或者其它XX了,表达能力就完善无缺了,这也有待考证。这个问题容我思考一阵子再来掰吃。
另外,不要把结合了其它范式的OO混到这个问题里来看,能力来自于哪里,如何得到的,这是一个需要分辨的事情。更加多余的我想说的就是,是否存在概念或任何其它东西聚合的实例,这样的东西就可以叫做OO了?那确实,如果把什么东西都当成OO,OO这个词也就利于不败了。一个简单的C Struct,你可以把它叫做对象吗?如果可以,这就是OO了吗?
所以我想,什么是OO,至少什么是OO的当前环境下的解释,还是要弄清楚的。之所以更新这段话,是因为参看了一些古老的争论和某些高人高论的反复;觉得很多事情是在SB的基础上,进行各种NB的推论。这样确实,周游世界的结果最终就是回归原点,“返璞归真”。也许我们觉得自己的思想境界提高了,但其实仍旧是一种屁话。
这样的研讨,除了应该得到的,比如了解过的各种东西使用的更加流畅,就再无其它建树了。因为该噎住你的地方仍旧在那里,仅仅是我们觉得“自然”了或者认为这是“问题本质带来的复杂”罢了。而多少“自然”的东西最终不自然了呢?
最后重申一遍: 不要因为OO存在这样那样的问题, 就放弃OO的尝试。 我的想法是, 作为一种当代最流行的方法, 没有一定程度的了解是不行的, 就像牛顿定律一样。 所以我倒是认为, 对OO的深入思考和练习, 虽然一时疑惑, 也绝非没有好处的; 尤其是当我们知道它可能存在问题这一点, 就更可以放开心态了。
过去一个高人对我说, 想学好数学先学好数学史; 我数学史不咋地。 今天我要说我们有一个大好机会, 因为我们就在历史里(这个历史看来还要持续几年); 如果我们认为OO不过是个大忽悠,不屑于学习OO体现了自我相对于云云大众的明智, 那么明天会如何, 就不好说了。
剩下的, 就是等脑袋兄的编译器小改款出炉了, 大家一起拿鞭子抽他干活...