TO redorange
虽然你说得很有道理,但忽视一个问题——关系和规律。在一个领域里面,关系规律是相对稳定的,类是体现关系和规律的(类似老师和学生),实体(对象) 是让关系和规律运作起来。并不是没有“我”,“老师”和“学生”的关系就不存在。对于实体类(其他的有方法类等),一般是成对出现的,因为他在说“老师”“教”“学生”。类当中含有关系和规律,为啥我们一般是说类图(单单描述了关系而已),而不会单单说一个类,也就是这个道理了。理解一句话:“是历史造就人,不是人造就历史”。类图主要目的是描述已经存在的关系。当然,领域里面还是存在角色(例如用户有会员和管理员等身份),于是有人就探索出场景这一词,其实可以理解在一个领域里面有多个小领域(场景)。
关于先有类还是先有实体,站在造物主的角度就知道了。要先有“人”的概念,才会有“你”,“我”,“他”,而我们却从“你”“我”“他”归纳出“人”,这里主要的区别是造物主是什么都知道(类似我们领域设计,在特定领域里面,我们就像造物主),而我们却不是什么都知道,或者有时什么都不知道(在上帝认识的全领域中,我们的认知明显有限的)。

当然,若果世界观不同,也会有不同的认识。(你完全可以认为上帝没有“人”概念,就做出“你我他”了)

2010年11月12日 11:33 "redorange"的内容
我们在编程的时候,总是先定义类,再来实例化对象。这看起来天经地义的举动却是违背认识规律的。也就是说,到底先有类还是先有实体 ...

这个观点很有意义,我仔细想了一下,在面向对象世界中,为什么我们有到底先有类还是先有实体这个疑问,肯定什么地方出错了或被误导了。

我认为是被所谓OO语言误导了,Java等语言第一步让你定义一个类,这其实是不真正OO的。见这篇帖子对于扩展继承的困惑,请大家帮忙
作者一上来就把角色定义为类或接口,然后在继承实现等具体战术中纠结,实际上他就是被语言误导了,他应该先找出实体。

实际中,我们进行软件开发时确实要经过一次转变,领域建模首先找到实体,然后再对应到语言级别的类,这个步骤和把实体转到数据库数据表一样生硬,很有将人话硬是翻译成鸟语的感觉。

人和机器(技术)永远是一对无法调和的矛盾,是真正的水和火,没有意识到这一点的技术人员,一般都是被机器奴隶的人,为什么奴隶社会那么长,因为是被洗脑原因,身在庐山中不识庐山真面貌。

有了这个意识,就知道计算机机器技术的发展终极方向,有自己的主见了,有自己对技术的独立认识了。

我觉得是造物者和物的角度问题,在我们物的角度,我们不可能扑捉世界的边界,但在造物者来说这个世界是有边界的,在有限的东西里面,可以提取出一个相对稳定的类,前提:存在边界。但物不同,在一个稳定的领域里面能提取出相对稳定的类,但领域一旦变化,这个类就不适合了,如同我上面的发言。当然这涉及人类认识的有限和无限了。所以说在一个相对稳定的领域中,类是存在的,而且先于实体。但类是片面适应的,或者说是静态的,他不能适应所有领域。

我们软件开发时,我们是以造物者的思维去思考问题的——存在边界。我们认为我们认知了领域内的所有东西,然后提取出幕后的类。在我们眼中往往是先有实体再有类,但造物者不是,他是先定义世界的规则(领域的规则,类:边界的约束,运动:交互规则)。

例如四维物体(只是推导出来的),我们觉得很不可思议,但我们世界的三维规则已经不适合它了,这就类似一个领域问题了。那三维和四维就没有类吗?有,在两个世界(领域)之外,在我们世界的实体是三维,在那个世界的实体是四维,大概就是这种意思了。

而在java中,可以说是一个java领域,我们是java领域造物主的思维,在创造世界的时候(做软件),需要设计(领域规则),但这个设计是需要反映我们现在的世界的,所以我们需要将能够模拟的地方放进去模拟出规则(不能模拟的地方就是人类和机器水火不容的地方,我们现在是把能模拟的地方探索出来和尽可能模拟)。为什么我们有时觉得上帝和人差不多,因为我们有时就是上帝(局限性的)。

PS:其实以前java给我更多的感觉是面向类编程,当引入哲学来指导和引入动态等相关东西的时候,才慢慢觉得开始OO了。很多人误会OO,是因为被语言所误导,以前的帖子我就说到OO不依赖具体语言的,语言只是OO的一种表现形式。

[该贴被SpeedVan于2010-11-13 14:03修改过]
[该贴被SpeedVan于2010-11-13 15:13修改过]
[该贴被SpeedVan于2010-11-13 15:17修改过]

之前的回应避开了redorange提出的“违背认识规律”的说法,是因为我不是完全赞同,偷了个懒,求同存异,让自己轻松一些,看banq也感兴趣,我也就再补充一下自己的看法。

对于类与对象的关系,或者说类型与值的关系,谁先谁后的关系,我倒不觉得是矛盾所在,类型本身在元编程中也可以被理解为是一个值。类是表达共性的概念,自然需要承载一些相对静态的特质,否则也就没有什么意义了;然而也正是相对静态的特性,限制了其动态表达个性的能力。

从共性入手,还是从个性入手;自顶向下,还是自下向顶,更多的时候我们是结合起来一起使用。当我们对全局胸有成足、一目了然时,自然可以从共性(比如类)入手,比较方便一些;当我们摸着石头过河时,只好先从个性(比如对象实体)入手,毕竟我们还没有窥见全貌嘛。对已知与未知的探索与这个好像也有点像。

PO(面向变量,一切皆变量)、OO(面向对象,一切皆对象)、CO(面向进程,一切皆进程)一般只是对某种范式的描述,承载了固有的历史含义,我个人不支持用这些特定的术语去等价“事物”这个概念,去包打天下,否则可能各执一词,而实质只是名字不同,却以为认识不同,还非要比个高下。进一步说,是反对这样去做,术语本身是为了促进交流与思考而定义的,对术语的混乱使用,将背离其初衷。

在程序领域,我之所以用“数据结构”表示“事物”这个概念,那是因为Niklaus Wirth是第一个思考或者道出程序本质的人。Niklaus Wirth先后设计了多种语言,且在软硬件上都有所成就,我真的很难相信(呵呵,好像有点盲目崇拜)他的对程序本质的概述及背后隐藏的世界观会如此“狭隘”。退一步说,如果真是这样(呵呵,呜呼哀哉,我自己也滥用了术语),那么在程序领域再找到一个合适的概念来等价表达“事物”也将万分困难,因为这个概念既要符合人们对事物的一般认知,也要包含程序领域本身的特性,很容易也将陷入“名可名,非常名”不可言说的困境中去。
[该贴被jdon007于2010-11-14 22:25修改过]

面向对象的罪状还包括:只能表达is-a的关系,而不能表达like-a的关系,等等,不过这些是表象而已。

维氏说:世界是所有事实(facts)的总和,而不是事物(things)的总和
The world is the totality of facts,not of things

得救之道,就在其中。

阿门!

事实这个概念,是不是可以理解为包含了事物及其活动。对“事实”进行解构后,会出现“事物”及“活动”的概念吗?或许维氏认为不能解构?

老子说,“无,名天地之始;有,名万物之母。”维氏所说的“事实”,在我看来,可能是类似于“有”与“无”未分离之前的东西,这个概念在老子中,称之为道。有点玄乎,适可而止。

你应该多给点提示,而且照顾一下,我们的认知习惯!呵呵。

我也是大而言之,不妨举一小例:

花是红的。

这就是一个事实,这句话实际上按照罗素发明的摹状词理论应该写为:

是红的(花)

这就是一个原子事实(atom fact)

这里面有两个名字,“花”,“是红的”,“花”是一个名字,“是红的”是一个摹状词,也就是谓词。

但不可以把它们拆开来分析“花”到底是什么?“是红的”到底是什么意思?因为分析的最基本单元就是facts,不可能拆开了。

因为世界是事实的总和,而不是事物的总和,原子事实已经是不可分析的基本单元了。

面向对象按我的观点来看,哲学观已经是很简陋的了,而实现上更是因陋就简,从始祖smalltalk开始,就是一代不如一代,而做为第一代OO的smalltalk,居然事实上成了OO史上从未被逾越的最高峰。

很刺耳,不过一些大师也说过类似的话,我是学他们的,哈哈。

对世界的终极本质这一问题,我认为自己是无力回答的,就像生命的意义一样,年少时的困惑不解,至今我仍没能力回答。

如果我的理解没有出错,维式的世界观,实际上是一种二元论的世界观,巧妙回避了一元论世界观“什么是第一性”的争论,是采用了“以退为进”的回答策略。而老子似乎更幽默一些,用了一个不可言说“道”,像是一元论的世界观,又像是二元论的世界观。

写到这,让我想起了以前自己建议朋友怎样处理“to be or not to be"类的问题。大意是,一种做法认为这个问题是真命题,值得作出选择;一种做法是认为这个问题是一个伪命题,取消问题。从维式的回答,大概可以看出他认为“第一性”的问题是个伪问题。但对“一元论”世界观的人来说,维式并没有给出答案。

你所说的得救之道,让我想起一部电视剧《天道》及其书《遥远的救世主》。这个问题不止在软件开发领域,在人生等其他领域一直存在着。

对哲学的兴趣已大不如从前,思考过度,活着就像梦游,让父母不放心。听过一个对哲学的比喻,我很喜欢,一个疯子(代表灵魂)在问问题,而一个傻子(代表大脑)却试图回答问题,很生动的画面呀。

“世界是由事实组成的”的观点,在世界观层次我心里没什么定论,只要解释的通、有指导意义的都会接受,而且这个观点比老子的“道”更简单、容易理解,蛮喜欢的。(其实,以前听过维特根斯的名言,也想过了解其作品,不知后来为何却不了了之。好在,亡羊补牢,为时未晚。)现在很想了解这个观点下对语言的设计与使用会产生什么样的影响,uda1341如果有深入的思考,不妨再给我们一些启示。哈哈。

《逻辑哲学论》-维特根斯坦(前期作品)
http://www.cnblogs.com/kavenmo/archive/2004/09/30/48197.html(中文)
《哲学研究》-维特根斯坦(后期作品)
ttp://www.voidspace.org.uk/psychology/wittgenstein/witt_index.shtml(英文)

我之所以引用维特根斯坦,忽悠的成份居多,哈(很多程序员也一样),这很大程度上是因为他的话很精炼,但他有些话又很难懂,看罗素的其实更好懂些,毕竟一个是奥地利人一个是英国人,英语作者的最大优点就是易懂。

要说体会,倒是有一些,不过没法指导在现有语言下的编程实践,只是用于指导我的新语言设计,卡壳的时候我就会到论坛上胡言乱语,所以这些思考都是进行中的,充满了错误和自相矛盾。

先说对这种理论的一个通俗解释:
在系统分析的时候我们经常会有一些陈述,这些陈述都是语言,没错吧。实际上思维是止于语言的,语言不可表达的,我们无法对其进行思考。我们对一个软件的系统分析,都可以归结为一组陈述,有一些陈述是最基本的,另外一些陈述是可以根据这些基本陈述推理出来的。分析哲学兴起之前,人们往往把这些陈述仅仅看做对世界的一个描述,而一些分析哲学家认为,这就是世界本身,世界就是由这些事实构成的。

试想,我们如果能够把系统分析时所做的那些陈述精确化,这些系统分析就成了程序本身,就不再需要我们转换成各种语言,各种范式去实现它们了。将这些陈述精确化的方法,是将其分析为一组原子事实,一系列的推理规则,和由这些推理规则所推导出来的所有事实,用逻辑学的工具去处理它们,而不是用机器(过程式),用数学(函数式)。

关于面向对象的继承,这是最让人头疼的事情,以至于面向对象的教科书里出现了不要轻易使用继承的警告,这就显得太荒诞了,继承是一种is-a关系,而在语言表达中,对is-a的处理就很复杂,更多的,是like-a关系。

太长了,我正在打算修改补充一下以前一篇用这种观点看待面向对象的文章,慢慢整理之后,再发上来供大家指正,大意是回到语言本身去处理面向对象,会出现很多不一样的特性,其中可能包括:

1 继承可用于函数,数据结构,操作符等乃至整个程序等而不仅仅限于类
2 如何表达like-a关系
3 设计时继承与运行时继承
4 类型演算,设计时的类型演算和运行时的类型演算

对语言我并没有宗教信仰,愿意接受任何有价值的思想的洗脑(洗脑于我是个中性的词,与洗脸有相似之处)。不过目前对一些形而下的东西还是有些偏爱,比如面向对象的点语法、大括号对、驼峰式书写格式等等,但这只是个人的审美习惯,不必求得共识。

帖子的名字中的Hello, World,只是因为这是个最简单的程序,也是一般程序员最早接触的程序,有“入门”之意。不过仔细想来,"Hello, World"应该有所深意。K&R使用自己发明的系统与语言,怀着对自然的敬意,轻轻地键入“你好,世界”,看着界面输出相应的结果,心中充满喜悦。这种情景可不可以理解为一种对“天人合一”的具体的描绘呢?“你好,世界”,多值得玩味的一句问候。

上面因为争论,不得不探讨世界观,而我现在觉得K&R的“Hello, World”却可能早已暗藏这一层深意。“你好,世界”,“你好,世界”,朗朗上口,令人遐思。哈哈,突然想到的一些东西,下面转入正题。

不止语言,我对四色原型的理解,也是基于“世界是由事物及其活动构成”的观点。在领域中找出事物(实体)及其活动(事件),并找出各种活动的关系,按照四色原型的指导,一块块地拼出“领域原型世界的版图”,这将是一幅非常自然的景象。“世界是由事实组成”,尽管不能确定这个观点是否是经过“易容术”的“二元论”(事实,可以解构为事物及其活动),但我不太关心这个。我关心的是在这种世界观的指导下,对于语言的设计与使用,甚至对领域模型的设计与使用,将会产生什么样深刻的影响?现有的方法是否可以从中借鉴、获益?

uda1341对“继承”的陈述挺有意思。在我看来,“继承”至少应当具备两种价值:1)在语义上,将一脉相承的客体、事实联系起来;2)在语用上,起到代码与数据的复用。呵呵,期待你的更多的论述。

一下子都发上来也不妥,我还是分主题,也比较好讨论。

先提前说个我觉得很重要的东西。

在现有的程序设计语言中,是完全没有时间的概念的,例如我们不可能写出这样的代码:
最简单的:
如果 X的上一个值是1,那么... ...
复杂一些的:
如果 X的值从0变为1,又从1变为0,那么... ...
复杂的:
如果 上次是执黑者下棋,那么 这次由执白者下棋。

而我们在进行系统分析时,由于我们是人,人是有记忆的,所以我们说话经常要用到记忆,不可避免的用到上面这样的描述。没有记忆,我们甚至无法判断在进行棋类游戏时,现在该由谁下棋。

现有的做法是,把记忆转化为一种机械装置,在每次下棋的过程中,嵌入这样一个操作,把当前下棋的棋子颜色记录在某个变量中。这就是把人类的自然表达方式,变成程序语言的过程,对于简单的问题,这样也许行得通,但是对于很复杂的问题,会碰到麻烦。

如果我们能在程序设计语言中,建立自动的记忆机制,提供对过去的查询,就可以更加适应人的思维方式。


2010年11月14日 10:32 "uda1341"的内容
我之所以引用维特根斯坦,忽悠的成份居多 ...

我喜欢简练的话,大道至简,所以,如果我们现在恢复文言文,实际是民众逻辑上一大进步,白话文实际是一种倒退,本来中国文字就因为象形性,而非逻辑性,结果白话文一下子变成一地鸡毛,从此中国人就再也没有思想(这得感谢鲁迅,他用推广白话文成就了他自己的千古第一骂,后无来者,后人再也无法超越他了,因为用白话文相当于自废思想武功了)。

维特根斯坦刚才看了一下,从我的屁股位置来看我有自己的一些理解,感觉是在做领域建模分析时碰到的一些原则,借此我总结成更加精炼的几句话,因为是白话文,罗嗦点,如果是文言文应该就是几个字:

世界是由事实组成的,而事实可分为实体等对象,分析事实时必须划清一个边界,任何真理或真命题都是有前提条件,也就是有边界的,无边界就无法言说,在边界中找出聚合核心,从事物之外(边界外)确定其意义(如关系活动规则),从事物内部去确定其特征。

打个比喻:事实facts可以看成是一个车,车的内部发动机可以看成是车活动的因;周围墙壁是车之外的环境,如果车碰到墙壁,发动机一直开足也没有用。所以,要表达一个事物,就从其外部和内部去描述,而外部和内部的划分关键就是边界。

关键就是最后一句,如何表达言说事物?关键就是找出边界,就像你切蛋糕,第一刀在哪里?围棋是一个边界争夺战(表面上看围棋是注重精于计算,如果真的是这样,你完全可以用机器战胜李昌镐,有这种观点的人实际上还是忽视哲学思想,注重细节的表现)。

[该贴被banq于2010-11-14 16:13修改过]

大家还是多关心一下javascript吧,一个不起眼的脚本语言,但是我认为它体现出的世界观是更符合实际的。
先从历史的角度解释为什么要先定义类:因为计算机要先申请储存空间,这个步骤是从汇编语言开始就形成的固有逻辑。之后被C继承,后来Java也延续了。但这个过程是与OO完全没有关系的,完全是出于“计算”的需要。
开辟内存空间这个步骤类似于先创建一个世界,然后这个世界才能承载里面的万事万物。
因此,我理解,定义类的这个过程不是编程者认为他是上帝,预先知道世界上有什么类型的事物和规律,而是一个对原先的纯计算过程的一个体现。有些语言,如C++,Java,把开辟内存空间这个过程与定义类协同起来,一个步骤干了两件事情。
这会产生一个固化现象,我之前有描述。
后来,脚本出现了,大家发现脚本可以随时定义变量。因为他们不需要一开始就申请储存空间。于是类就可有可无了。一个脚本编写运行下来,可以全都是实体,没有类。
实际上,正如jdon007所言,类里面的属性实际上是共性,实例化后的对象的属性,实际上是个性。共性只有当我们需要对个性归类时才有意义。
对类的定义,从认识论上来说,是一个相对的过程。有先哲说:“人不可能两次踏进同一条河”。因为如果人根据时间的不同,而把那条河归为不同的类,一种是刚才的河,一种是现在的河。他们的河水因为时间的不同而完全不同。
因此,人对事物的分类,或者说对事物的共性的归纳,或者说对事物的类的定义是一个相对过程。而现在我们常用的OO语言,却不承认这种相对性。
而javascript作为脚本,完全没有历史包袱,也没有计算机运算方式的束缚。它更关心面向对象的本质是什么。那就是面向对象,不面向类。
最后,javascript有个重要的概念是prototype,中文翻译为原型。实际上我更觉得它应该叫“共性”。在javascript中,当对象没有某个属性时,它就会到对象的prototype属性中去找。个性优于共性,共性是个性的补充。