哈哈,redorange对原型的解释非常精彩,这是良性互动交流的效果呀。一下打通了我对“原型链”与“类继承体系”的认识,两者采用了相反的策略,前者从个性入手,后者从共性开始,前者认为共性是个性的补充,后者却让共性制约着个性。顿悟的感觉真好,呵呵。

被JavaScript的发明人Brendan Eich称为“lambda编程和JavaScript的精神领袖”Douglas Crockford,也认为Javascript是一门精华与糟粕并存的语言,不过“瑕不掩瑜”,Javascript语言体现的智慧确实值得学习。

到底是共性约束个性的“严谨”好,还是个性突破共性的“灵活”好,这恐怕是未来争论的又一个话题。

哇呜~~~~哲学大交流又来了-。-jdon快变成哲学论坛了,哲学帖子更新多过技术帖子╮(╯▽╰)╭

我也发表观点。

关于个性和共性那个好,我感觉有点像有鸡先还是有蛋先的问题,思维会无限循环-。-蛋生鸡,鸡生蛋,共性从个性提取,共性在某个场景下又成了个性。我们不断探求鸡先蛋先,就像探求个性先还是共性先,鸡和蛋探回过去,个性和共性则探到制造这个世界的造物主那里了-。-只有造物主那里才有答案。问题人类能到达那个地方吗?未来很长的一段时期还不能到达那种地步,我们暂时可以认为无法达到,于是我们暂时可以肯定共性和个性是并存关系。

那么回到软件开发领域(很多时候我们都会加入前提,也就是约束,额外话了),在现在的软件领域,我们是如何做的呢?这里先放下,我们再看看共性和个性的四种认识顺序方式:1、共->个->共;2、个->共->个;3、共<->个;4、个<->共。好了,现在再拿起原来的问题,我们的做法明显是第四种。从原来的世界的有限认识提取出共性,把这种共性作为类,再到软件中去产生个性。
好吧,我拿出唯物辩证再说:(黑字部分摘自网上,懒得打了)

矛盾的共性指矛盾的普遍性,是绝对的、无条件的;矛盾的个性指矛盾的特殊性,是相对的、有条件的。矛盾共性与个性的辩证关系是指,共性寓于个性之中,个性又受共性的制约,共性和个性在一定条件下相互转化。

共性与个性的关系是关于矛盾问题的精髓
(1)共性与个性问题是理解对立统一规律诸问题的钥匙。共性与个性的原理贯穿于对立统一规律诸问题的一切方面,是把握矛盾诸问题的一条主线。
(2)共性与个性的原理是分析和解决矛盾问题的根本原理。只有掌握共性与个性的原理,才能依据矛盾普遍性的原理对具体矛盾进行具体分析,正确认识矛盾和解决矛盾。
(3)共性与个性的辩证关系又是正确理解和认识辩证运动的钥匙,人的认识过程由个别到一般,又由一般到个别,它是共性与个性矛盾的展开,不理解这一原理,就不能正确认识事物。

共性与个性,就是一组彩色铅笔,共性是书写绘画工具,都是铅笔,个性是不同颜色。

所以同一个问题认识的区别在于问题的把握不同侧面。

而我们造软件是,是一个作为物的人类,去创造一个类似的世界。我之前说到了,身为物的我们对世界的认识是片面的,为了能全面造出一个世界,我们只能约束起来,约束在一个领域内(类似财务,把财务作为一个世界,没有其他东西)。而为什么javaScript造界面时,会这么好,因为界面正好是不想被约束的地方,所以觉得javaScript很舒服。使用类,是为了约束,是为了对领域扑捉的准确性,灵活,如何实现准确扑捉呢?很期待能给出个例子,让我好好开下眼界,毕竟我认识尚少-。-。

我们不要为做软件而做软件,要从本来目的出发。共性和个性本来是平等的,但因为“前提”会使平衡打破,所以谈到实际上,需要加入前提;谈哲学,则要抛开这些。例如在考虑软件开发的OO,我们也要想到人脑和电脑的区别等一系列前提条件,不能直接到达哲学上。



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

redorange提出的问题,答案应该取决于应用场景吧。这里,我想提出的另一个问题是:类与对象,也就是共性与个性的作用如何发挥并有效地结合起来?之前说的在对全局有把握时可以从共性入手,在摸着石头过河时,可以从个性入手,但这只是对共性与个性的作用一种具体运用。显然它们之间的“珠联璧合”,不应该仅限于此。那么在建模及编写代码是如何对其进行有效的分工和合作呢?

现今主流的面向对象语言在编译前是一个以“类”为主导的世界,在编译后是一个以“对象”为主导的世界。编译过程就像一道鸿沟,使得程序员难以清晰地预见真正的“对象世界”。

在领域模型中,什么是共性?什么是个性?可能经常出现的是,领域模型的结构相对稳定,而其行为则相对多样。因此可以考虑用类表达领域模型的结构,用对象来表达领域模型的行为。但如何实现这种效果?

DCI从名字上,似乎提供一种解决方案,数据(D)表示结构,交互(I)表示行为,上下文(C)表示结构与行为结合的环境。不同的领域行为根据上下文注入到相应的领域结构中。

“注入”行为,目标是为了表达行为的动态个性,其原因是松开类机制将“结构”与“行为”的捆绑,从而不得不使用的一种手段。在过程化的语言,显然不会出现“注入”这一现象,在用C语言模拟类的机制中,可以看出对类结构的继承是约束的,而对象的行为又是自由。Javascript可以使用构造函数与原型的结合,起到相似的效果。

从上面的分析,可以看出DCI的作用似乎是在类继承体系抽离出行为(interaction)来,仅保留结构部分(data),而后根据上下文(context)注入。从语言范式的角度看,这是对对象属性与行为的一次松绑,而又通过注入机制将其动态捆绑,所以也并没有完全松开。具体如何实现,现在我还不清楚,不过banq好像提及了一些开源框架。

2010年11月12日 11:33 "redorange"的内容
你本人在家是家长,在学校是老师,在工作岗位是员工。家长、老师、员工都是不同的类,而这些不同的类都指向同一实体。 ...

今天想明白了如何处理这个问题,DCI范式就是现成解决方案。DCI范式是个非常好的范式,其中领域模型(Data)类发挥了类约束的作用,在具体的场景(Context)中将角色职责注入(Interaction)给实例化后的领域模型对象,可以有效地解决上面问题。此外引入DCI范式,场景(用例)本身可“对修改封闭,对扩展开放”、添加新场景也比较容易、编译后的对象世界也变得可预见、代码的可读性大大提高等诸多优点,要仔细阐述其来龙去脉可能需要一个新帖。如果你对四色原型、MVC比较熟悉,不妨结合它们去理解DCI, D、C、I与四色原型中PPT、MI、Role几乎是一一对应的关系,DCI与MVC是互补、对称的范式,两者结合可能可以形成一种更丰富的范式。

DCI算是Jdon给我四色原型、领域驱动后,又一个提示。有一点小小的遗憾,Jdon上解释这些术语时,往往没有做到深入浅出,就我个人而言常是去看原出处才弄明白。不过Jdon给了提示,这具有方向性的意义,感谢banq、Jdon。很想知道banq是如何在偌大的网络中与之有缘相遇?呵呵。

2010年11月17日 23:35 "jdon007"的内容
,DCI与MVC是互补、对称的范式,两者结合可能可以形成一种更丰富的范式。 ...

DCI是可以替代MVC的,是一种竞争关系,MVC模式已死,相信对你的思路有帮助。

多谢你肯定,jdon一直在关注软件设计领域新动向,从04年开站以来,几乎全球软件行业的重大设计革新都有涉及,见这里:http://www.jdon.com/aboutsite.htm。因为专业,所以深刻。呵呵。

2010年11月18日 10:24 "banq"的内容
顶一下2010年11月12日 11:33 "redorange"的言论
你本人在家是家长,在学校是老师,在工作岗位是员工。家长、老师、员工都是不同的类,而这些不同的类都指向同一实体。 ...


今天想明白了如何处理这个问题,DC ...

这明明是多态嘛,一群大忽悠啊!!!

to lqtcts
拜托,应该是角色问题吧。
至少有两点值得商榷:
1、我们可以将家长、老师、员工作为“人”这一基类,产生不同的特征和行为,但是当我们实例化子类后,得到了不同的对象。如何判断得到的不同对象在现实中就是同一个人呢?
我们可以通过某种虚拟特征来认定,比如id号码。这需要在实例化时就传递到对象里,就好像是注入了灵魂。
2、老师、员工作为一个独立的概念,并不一定是人这个概念的子概念。机器人也可以充当老师、员工。只要某种事物符合老师的特征就可以了。也就是从个性归纳出共性。当然,你可以认定所有的老师或员工都必须是人,但这种认识世界的方法是否太机械,太不智能了呢。
当别人说:“兴趣是最好的老师,狗是人类忠实的朋友”。我们是否能跳起来说:“你错了!老师和朋友都必须是人,不能是其他的乱七八糟的东西”。

2010年11月18日 17:56 "redorange"的内容
to lqtcts
拜托,应该是角色问题吧。
至少有两点值得商榷:
1、我们可以将家长、老师、员工作为“人”这一基类,产生不同的特征和行为,但是当我们实例化子类后,得到了不同的对象。如何判断得到的不同对象在现实中就是同一个人呢?
我 ...

那条狗当然不是人啦,它是动物嘛,人也是动物撒

2010年11月18日 16:21 "lqtcts"的内容
今天想明白了如何处理这个问题,DC ...
这明明是多态嘛,一群大忽悠啊!!! ...

如果你觉得是多态,相信这个帖子问题你可以解答:对于扩展继承的困惑,请大家帮忙

现在很多人现状是理论和实践脱离,谈起OO一套,做起来还是面向数据表,关键就在这里。

2010年11月18日 17:56 "redorange"的内容
顶一下2010年11月12日 11:33 "redorange"的言论
你本人在家是家长,在学校是老师,在工作岗位是员工。家长、老师、员工都是不同的类,而这些不同的类都指向同一实体。 ... ...


注意哈,‘不同的类都指向同一实体’,这个的意思,无非就是说的人啊、狗啊什么的都是属于动物这个类,人啊、狗啊没有被实例化时,都是指向该类的,一旦被实例化后,就是具体的实体了。 java中Object类不是这样的么,任何对象都是Object类实例化来的。这就是java中的多态啊,呵呵...

2010年11月18日 20:09 "lqtcts"的内容
java中Object类不是这样的么,任何对象都是Object类实例化来的。这就是java中的多态啊,呵呵... ...

首先,个人以为你对多态这一术语上的含义也许并没有真正了解。

多态,一般说来是指对同一条消息各个同类对象有不同的响应或处理方法。比如张三告诉李四和王五,你彩票中奖了(人民币2亿)这个消息。李四听到这个消息,高兴得大喊大叫;王五听到这个消息,则兴奋至极,晕倒在地。这就是生活中的多态现象。

而现在的问题是,一个对象隶属多个类(“即不同的类指向同一实体”),这实际上是多重继承的概念,在Java中可用实现多个接口达到这种效果。这不是多态的问题,但可以使用多重继承机制解决,但多重继承解决的效果怎样?

试想,假定小李这个人的类是父亲。一天他来到父母面前,又变成儿子这个类,于是我们定义小李这个人的类别,既要让他隶属父亲这个类,也要让它隶属儿子这个类。恩,不错,代码跑得起来。又一天他来到爷爷奶奶面前,又变成了孙子这个类,这个容易,我们再让小李继承孙子这个类,不久OK了。看出问题来了吗?父亲、儿子、孙子与其说是类别的不同,不如说角色的不同。那么为什么角色不同,那是因为场景不同(面对儿子、父母还是爷爷奶奶)。

而DCI就是根据不同的场景,赋予对象不同的角色的一种解决方案。当然DCI的价值远不止于这点,DCI范式与MVC范式都是Trygve Reenskaug提出的,前后相隔40年左右。冲着,MVC架构的盛行与Trygve Reenskaug50余年的软件生涯,如果你有时间不妨去了解一下他老人家的智慧。

2010年11月18日 20:09 "lqtcts"的内容
无非就是说的人啊、狗啊什么的都是属于动物这个类 ...

的确,多态可以,但当定义人的行为和定义狗的行为是完全不相等的时候或者极少相等,而相对稳定的属性又相同时,就会出现在某种状态下,仍然可以执行另外一些不相干状态下的行为——万能类,动物变成万能类了。当角色大量的时候,用子类又不适合——出现大量的角色类。

而且业务增删改的频率往往远远大于结构增删改的,将行为松绑有利于行为的扩展和配置。

对于不同情况作出不同设计,这就是设计。


至于多态的选择,和系统倾向有关,也与世界观有关。java缺少对动态行为支持,是需要反思的。

约束与灵活是应该并存的。

我觉得,这里存在一个本我和物我的区分。本我的属性是事物的固有属性,物我的属性是外界赋予本我的属性。
多态可以解决本我的问题,但不易解决物我的问题。
进一步讲,有一部分属性是在相对长的范围内存在,直到发生质变。质变就是完全与现有的分类无关。如人变成了尸体。我们把这部分相对固定的属性成为内在属性。
其它的一些属性,他们或随着场景、上下文、角色等外部条件的不同,而产生变化。我们称其为外部属性。
如果要用软件描述世界,就一定要分清楚内外属性的异同。

2010年11月18日 23:33 "redorange"的内容
如果要用软件描述世界,就一定要分清楚内外属性的异同。 ...

在思考语言范式时,我曾这样想过,面向对象,行为与属性绑得太紧,面向过程,行为与属性放得的太松。但这里不是仅仅选择“分”或“合”那么简单,“贫血模型”与“充血模型”实际上与“面向过程”与“面向类(对象)”的矛盾是相似的。

“贫血对象”是将“行为”与“属性”完全放开的一种表达,而“充血对象”则又矫枉过正,把“行为与属性”绑得太紧。

类是表达共性的概念,而对象则是充满个性,而且这些个性是依赖场景的,离开场景将失去意义。所以,在“充血模型”中,用类表达对象时,实际是将“个性”统统视为“共性”,在任何具体的场景中,对象的角色或职责都已经定义好了,这显然是不合适,因为一个对象可以多种角色参与不同的活动或场景(可能使得类继承体系非常庞大和复杂),而且在参与新的活动或者场景时,以“类”及“继承”的方式定义对象则更是力不从心。

而在“贫血模型”中,则将“共性”统统视为“个性”,这是抹掉“共性”的做法,与“充血模型”抹掉“个性”的做法刚好相反。前者是“白马非马”,后者则是“白马即马”。都没有协调好“共性”与“个性”的关系。

因此真正自然的“领域模型”应该是这样的,如果对象的某些行为在任何场景都是通用的,那么就放在领域中去,将其绑定,这是尊重“共性”的约束;如果对象的某些依赖于具体的场景,那么则在具体的场景中注入相应的行为,赋予对象相应的角色,这是尊重“个性”的自由。

那么“贫血模型”与“充血模型”,就没有用了吗?也许是。但这两个概念还有意义的:“贫血模型”与“充血模型”实际表达的是两个极端的情景。如果一个对象,没有任何共性的行为,其行为完全依赖于场景,则可用“贫血模型”表达;如果一对象,在所有的场景,都是以同样的角色身份参与,那么可用“充血模型”表达。

“贫血模型”与“充血模型”都可以实现领域建模,与“面向过程”与“面向对象”都可以描述一切画面一样。只是针对的问题不同时,有合适与不合适的差别。

所以,对象的行为该不该放入“领域模型”,我们要先分析一下这些行为是对象所固有的,还是依赖于场景的,如果是固有的,即是共性的,就放入领域模型(domain),如果不是则延迟在具体的场景(service)中注入,赋予其角色的个性(DCI)。

那么设计模式将如何运用呢?

设计模式可以在领域模型中使用(domain),也可以在具体业务场景(service)中使用。设计模式是在局部、微观层面的一种支持变化的机制,在具体业务场景中使用再合适不过了。将来可能会出现的现象是,在领域层(domain)各个模型中用的更多是“结构型”模式,而在业务层或服务层(service)的各个场景中用得更多的是“行为型”模式,两者都可以使用“创建型”模式。

此外,我认为DCI与MVC是互补(对称)而不取代的关系,这点与banq不同。有时间,我将描述自己如何从不同的思路得出这个结论,尽量浅显易懂,让更多的人理解,Jdon有时的讨论,让人不知所云,也许有话题较深入的原因,但也不能不自我反省。此外,我上面的分析,没有道出领域建模的真正意义和OO最初的构想(梦想),以后有时间一块补上。