呵呵,顺便问三个个题外话的问题:
1)方法调用和消息传递的关系是什么样的?
2)OO中,对象的关系通过对象引用来实现和通过类似于数据库的ID方式来通过唯一ID来关联有什么本质区别吗?我们真的应该采用对象引用才是合理的吗?有这个疑问是因为我经常发现对象引用在很多时候都是累赘,比如我很多时候只想知道被引用对象的ID即可,但是在对象引用的情况下,会把整个被引用对象查询出来我才会知道其ID。
3)对象的属性有必要都设计为只读吗?只读之后属性只能通过对象自己的方法才能修改;属性的初始值只能从构造函数传进来;但是我发现如果真的都是只读的话,在编码上会很麻烦。尤其是在对象属性比较多的情况下。虽然可以通过值对象将一些具有相同变化率(嘿嘿,变化率这个词语也是从jdon007你那里学来的呢)的属性放在一起从而来减少一些属性,但有时还是会有很多属性,要是这么多属性都通过构造函数进行初始化,那实现起来实在比较麻烦。之所以有这个疑问是因为在DDD中,我了解到领域对象的属性应该是业务安全的,即属性不能被随便更改,否则和普通的数据没区别了。领域对象的状态应该由对象自己去更改,即别的对象发送消息给当前领域对象,当前领域对象接受消息执行消息,从而状态改变。

之所以问这三个问题是因为他们一直困扰着我。始终没想要该如何设计。
[该贴被tangxuehua于2011-07-30 14:40修改过]
[该贴被tangxuehua于2011-07-30 14:51修改过]

1)在以前的一个帖子《Hello, world》我心中的道,引用Niklaus Wirth的话,也许可以回答你的第一个问题。

Niklaus Wirth 认为面向过程与面向对象的主要术语是同义词:
variable = object
procedure = method
parameter = message
calling a procedure = sending a message
data type = object class

2) 对象的引用本质是一个只读的指针,其值是一块内存的物理地址,是对象的唯一的物理标识。

不知道你所说对象的ID是什么?是对象的唯一的逻辑标识?而且设计时把数据库中的每条记录的ID,作为对象的唯一的逻辑标识?放入对象的内部?

如果把对象的唯一的物理标识,取个有意义的别名,作为唯一的逻辑标识?你就不需要把整个对象查询出来,才知道其逻辑ID。

也就是说你只要把对象名作为对象的逻辑ID,就不需要进入对象的内部,去查询其逻辑ID了。

还有“对象引用”不是“类引用”,其类名是不能作为对象的逻辑标识,除非你不关心是哪个对象,只关心是哪类对象。

3)变化率一词,初中代数就有呀,呵呵。至于属性变化率,那是从Kent Beck的《实现模式》那本书看到的。

属性很多时,可根据变化率凝聚若干属性为一个整体,剥离出来。

对象的属性最好设计成只能自己修改,别的对象想改的话,只能通过其提供的接口进行修改。对象之间是相对独立的,通过消息传递来交互。

如果是常量对象的话,就全部开放,不需要接口的隔离。

对象创建时各个属性需要的值,可以通过框架的配置自行注入。这是把工作转移量转移到配置上,属性多时还是麻烦。

所以,除了凝聚属性,还可以采用重载构造函数的办法。

只要在有必要时,才对对象的所有属性进行一步到位的初始化;否则只需要初始化一部分属性,其他属性在需要时再通过setter进行赋值,也就是分时间段进行赋值。

属性的赋值工作,可以结合使用框架的构造注入(constructor)和设置注入(setter)方式。

总结一下,当对象的属性很多,有两个思路。一个对属性分组进行赋值(空间划分);二是对属性分段进行赋值(时间划分)。设值工作可以交给框架去做,可结合使用两种注入技术。

2011年07月30日 14:13 "@tangxuehua"的内容
但是行为过程在花木兰以及借书的的例子中如何体现呢? ...

行为特征的刻画方式,可以通过“角色”(行为结果),也可以通过“(时间)函数”(行为过程)来刻画。

DCI的I的角度就是从“行为过程”来设计的,即在场景中模型绑定或被注入一段代码。

给这套建模原语取个名字吧:四象图。突然想起以前在自学机器学习时,总结过一套分析方法,也命名为四象分析法(用以描述属性跃迁或状态转移,不过与这套建模原语内容上没啥关系),都有点淡忘了。易经中有两仪四象的说法,动画片《火影忍者》中有四象封印术。取这么个老掉牙的名字,算是对先人智慧的一种敬意吧。

建模原语:四象图,喜欢的人不妨将其推而广之。在此先道声谢谢,呵呵。

行为过程是指模型被注入行为的过程吗?这个过程的结果就是行为结果,即角色。模型有时候除了可能会被注入行为之外,还会被注入状态,这个也算是行为过程吗?

你说的两个过程不一样:一个是用来“刻画”特征,一个是表示模型“凝聚”特征的过程。

行为特征可以表示为一个类(比如角色、比如事件监听器),可以表示为一个函数(比如function() {}),
状态特征可以表示为一个类(比如颜色、金额),也可以表示一个函数(比如2t+3)。

特征可以有更多的表达形式,甚至我们还不知道的形式。

行为特征与状态特征的区别不在于其在表现形式,在于从模型剥离出来的角度。

状态特征考虑模型部分特征的“一致性”从“模型”上剥离;
行为特征考虑模型部分特征的“交互性”从“模型”上剥离;

状态特征与行为特征,都是模型的特征,严格区分它们不是特别重要,
倘若特征剥离从两个角度都说得通,此时区分是模型的状态特征还是行为特征就没有必要了。

特征剥离的基本目标有两个:1)复用状态和行为特征;2)使模型更精炼。

注入,是模型在场景凝聚特征的一种方式,状态和行为特征都可以。

关于模型在场景中凝聚特征的方式,简单的可以通过传参的方式。
比如把状态特征和行为特征通过作为模型的构造参数传递进去。

还可以考虑使用设计模式进行特征凝聚,比如通过模型绑定事件监听器来凝聚行为特征(观察者模式),通过组合方式凝聚多个状态特征(组合模式)。

在前面,我已经写了一点关于场景中模型如何凝聚特征的思考。

结构型模式和行为型模式分别是模型凝聚状态特征和行为特征的有效工具,可以根据场景特点,灵活选择。

从模型上剥离特征(分),模型凝聚特征(合)的方式,是一个开放的课题,我只是在方向上,考虑了个大概。比如剥离的角度,一致性、交互性;凝聚的方式,结构型模式、行为型模式等。

你可以使用这套原语重新组织你的论坛代码。我在这里开个头。

模型:帐号、帖子、论坛
状态特征:帐号类型、帖子类型、帖子状态(置顶、锁定等)、论坛状态(主题总数,帖子总数,最新的帖子ID等)
行为特征:
场景:发帖子、跟贴等

这里模型好像没有明显的交互特征,业务场景相对单一,没有剥离的必要。
假如该帐号不仅可以用在论坛,也可以用在图书馆系统中,
那么帐号的行为特征就可以剥离出来,分成两类,一个与论坛有关的,一个与图书馆系统有关的。

发现图书馆的那个例子,有问题,需要修正一下。

图书卡这个现实中的事物,在系统中的映射实际上是帐号。
图书卡是用户在现实中使用的工具,帐号是用户在系统上使用的工具。
所以把Card全部改为Account,就可以了。
而且Account上的行为特征也可以剥离,如果Account的用途不仅仅在图书馆领域上,仅仅考虑图书馆领域时就不需要剥离。

帖子与图书基本上很相似。但还是有区别,帖子没有依赖场景的行为特征,图书却有(BorrowedBook)。

行为特征,一种直白的解释就是模型依赖于场景的用途,跟之前讨论的角色很相似,在定义行为特征时,角色是作为其别名的,所以关于角色的认识仍有效。
[该贴被jdon007于2011-07-31 01:21修改过]

2011年07月31日 01:16 "@jdon007"的内容
状态特征与行为特征,都是模型的特征,严格区分它们不是特别重要,
倘若特征剥离从两个角度都说得通,此时区分是模型的状态特征还是行为特征就没有必要了。 ...

状态特征也可以理解为从模型上剥离的结构特征。

豆瓣上的
程序之道:象数理
建模原语:四象图
这两个帖子记录了这近一年我对软件开发的思考过程与结论,在Jdon上的帖子分别是
Hello,world! - 我心中的道
领域驱动之我见

如果能早5-10年接触计算机,或许我现在会和banq一样成为一位软件技术专家。不过作为软件开发队伍中的一个小兵,我也不感觉遗憾。毕竟,"Better late than never"。 我们都很幸运,有机会接触这个前所未有的学科。

在SICP一书中的前言说道,“计算机科学”并不是一种科学,而且其重要性也与计算机本身并无太大关系。计算机革命是有关我们如何去思考的方式,以及我们如何去表达自己的思考的一个革命。

与banq提倡用“象”去“数”的观点不尽相同,我认为“象”与“数”都是我们思考的方式,就像我们的“右脑”与“左脑”,“左手”与“右手”,“左眼”与“右眼”,舍弃其中的任何一个,我们都有可能会变得偏执,迈向智慧之路会走得更为艰辛。

《程序之道:象数理》和《建模原语:四象图》这两个帖子不仅描述了我的思考过程和结果,也描述了我如何去思考。从SICP对计算机革命的定义上来看,我想我算得上一名加入计算机革命的战士,一位计算机革命者,犹如一位无产阶级革命者。呵呵。
[该贴被jdon007于2011-07-31 11:36修改过]

关于特征已经写了不少,下面再写一点关于场景的思考,算是终结吧。因为我已经倾囊相赠,拿不出更好的东西了。

场景可分为两大类:查询和命令,前者是观察模型及其特征,后者是让诸多模型凝聚特征一起做事情。

场景中模型凝聚行为特征的方式,可以是EDA,或所谓的Domain Events。

这套原语也可以从MVC的角度去理解。MVC的M表示模型,VC可以理解为场景,V和C将场景分为两大类,V表示从观察模型,C表示从控制模型。

从系统论的角度看,模型与特征(结构/状态和行为两个角度)是对系统的内部描述,场景时对系统的外部描述。

外部描述可以从很多个角度进行分类,比如输出、输入;比如查询、命令;比如视图、控制器;比如读和写;比如视图和触发器;其实它们是相通的。

这套原语用于理解和学习界面设计、数据库设计、领域模型设计都是可以的。原语,承载的是一种思想,一种看事物、看系统的思想,不会在乎你用它来看那种具体的东西,比如界面、比如数据库、比如领域,因为它是建模原语,不仅仅是数据库、界面或领域的原语,只要你想用,就有用。

这套原语可以从MVC、CQRS、DCI、四色原型、DDD、EDA、Domain Events、REST等甚至更多我们都还不知道的角度去理解和使用,原语本身不会去限定使用原语的角度,更不会去限定原语具体的实现方式,因为这套原语背后的数学描述实际上是“无为”的。

FDD:Feature特征驱动开发

特征定义:<action> <result> <object>, 如: ´Calculate the total of a sale´ or ´Validate the password of a user´.

是不是和你的行为特征类似?FDD是配合四色原型的MDD开发方式。
[该贴被banq于2011-07-31 19:18修改过]

2011年07月31日 17:44 "@banq"的内容
是不是和你的行为特征类似?FDD是配合四色原型的MDD开发方式。 ...

FDD是Peter Coad等人的著作《Java Modeling In Color With UML》中第6章提出来的,是四色原型的产物。

可以从FDD去理解,也可以从四色原型去理解,因为这套原语的目标之一是作为在分析、设计、实现三个阶段的通用词汇,分析即设计,设计即实现。

原语允许从FDD、DDD、DCI、MVC、CQRS、EDA等任何一个角度去解释。之所以具备这个能力,因为原语的数学描述实际上“什么都没说,但什么也都说了”。

原语,以“模型”为中心,“特征”与“场景”为两个基本点。“特征”是场景中从“模型”身上人为剥离(分)出来的,所以要在
“场景”中人为重新凝聚(合)。特征剥离有两个基本角度:一致性与交互性;特征凝聚也有两个基本策略:结构型模式和行为模式。简单时,不需要使用设计模式。

原语没有强制规定行为特征要怎么表示,可以通过函数,可以通过类(比如角色、事件监听器)。特征的数学描述就是一组时间函数,而世界上所有东西都可以视为时间函数,所以这个定义也是:“啥都没说,但啥也都说了”。但因为此,原语才具有包容性。

2011年07月31日 19:08 "@jdon007"的内容
原语,以“模型”为中心,“特征”与“场景”为两个基本点。 ...

一个中心,两个基本点。

2011年07月31日 19:20 "@banq"的内容
一个中心,两个基本点。 ...

呵呵,banq,这倒是精简,都想到国策了。如果说四象图是原语的图形描述,那么这句话就是原语的文字描述了。我个人是常用它们来学习新东西、总结旧东西的,感觉还是蛮有效的,原语算是做加减法(为学日益,为道日损)的一个工具吧。

不过,我个人认为“特征”一词还比较有限,还有“约束”:http://www.jdon.com/jivejdon/thread/41088/20#23135610

在 “职责驱动开发”中,将“构造invention、 约束表达、规格Specification, 特征和描述Description”都视为“职责”。

也许“约束”可以用“场景”来表达。

我的意思是:事物之中有很多定义,是否可以将所有这些定义都归结为“特征”和“场景”,如果是,那么“职责驱动开发”是否也是将这些定义都归结为“职责”这个原语?

原语是把职责(或角色)作为描述“行为特征”的一种方式或角度。
职责,意重指“谁之责”?而行为特征,关心“what"甚于关心“who"或"which"。

其次,原语不是以特征或场景为中心,是以模型为中心,特征或场景是两个基本点,是附属。不论是“职责驱动开发”还是“特征驱动开发”,中心都从模型转移到别的方面去了。

模型的数学描述是一组时间函数。
场景的数学描述实际上是在描述一段时间内的模型。
这两个定义是极具包容性的。

特征是为了让模型复用及精简模型而人为分离的概念,在场景中需要人为地进行合成。

“约束”是模型(如花木兰)在特定的时间段内(场景中,如在战场作战),会凝聚怎么样的特征(披上戎装,行将军之职),这是场景的规约(Specification)。

隐喻和例子是非常有用的,但也是危险的,如果被困于隐喻或例子中。

2011年08月02日 09:01 "@jdon007"的内容
模型的数学描述是一组时间函数。 ...

还是不要叫模型,容易和其他模型混淆,如DDD的模型是指整个领域模型。对于时间函数,我的理解是状态综合体,我不去确定为时间函数,是因为不知道是否存在不因时间限制而实体模型,或者说整体领域是否可以在某种情况下忽略时间概念。打个比方,我被人打x下,我就会肿f(x)块,我只关注这个事情,那么我还是不是时间函数?又或者我在不同环境下,状态不同又该如何用时间描述?

2011年08月02日 09:01 "@jdon007"的内容
会凝聚怎么样的特征(披上戎装,行将军之职) ...

这里的特征写法有:

披上戎装=true;
行将军之职=true;

装备=戎装;
行为=function 将军之职();(或者动态注入方法)

可能不止两种,但特征仍然是一个整体,而不是true或是戎装或是function 将军之职()。


[该贴被SpeedVan于2011-08-02 13:06修改过]

2011年08月02日 13:04 "@SpeedVan"的内容
但特征仍然是一个整体 ...

我说过特征不是一个整体?我说过特征只能是true或false? 我压根就没有规定特征要怎么表示。我想你不妨仔细看完帖子,再回复不迟。

这种争论的方式,我真的很无语:假设你是错的,那么你是错的。所以关于特征的理解,我想我们无需再争论,各持己见吧。或者你尝试去把你观点解释给其他人听吧,听听别人的意见。

OO本身没啥错,但非得把那两个圈筘在自个脑袋上,我也不好说啥。

不关心时间,不意味着时间不存在。你可以有完全错误的时空观,甚至可以说,因为我看不见或者说我不关心,它就不存在,因为这是人意识的自由。

原语,不理解或反对就当作没看见吧。老实说,我也只期待对一些人有用,看清一大堆buzzword背后的真相,不迷失于其中,能腾出更多的时间和精力来做别的事情,仅此而已。