屁股上面的钉子

11-06-17 IceQi
在没有OO概念的群体里忙活,看到了他们的困惑却无能为力。兄弟们从接触软件的第一眼看到的就是错误的东西,而且已经成为了根深蒂固的思想,然后这也成了团队的思想。。。。

那句英文很形象:屁股上面的钉子。疼啊

banq
2011-06-18 19:19
中国话:坐在火山上的屁股。

gaofangjian
2011-06-21 17:52
没有OO我们的软件世界的问题有这么严重么?
面向过程编程存在了这么久,现在还继续的很好的活着。这又说明了什么?
存在就是合理。
我不是在否认面向对象的思想来认识世界的自然性和合理性,我只是想说
我们就是想将现实世界抽象到计算机世界,我们一直在追求那种自然的简单的
抽象方法。我个人也比较喜欢面向对象的思想,但是用来分析还不错,后面的
OOD,OOP,再加上可爱的关系型数据库,使面向对象能够工程化铺开很难。

而且我遇到的一个更大的问题是,现实世界往往都是虚假的,不确定的(需求),
当我们用尽心思分析好了,有了传说中的领域模型,有了近乎完美的设计方案,
有了优雅的对象模式之后,现实世界无情的变了,我们怎么办?
现在很多时候,我都是被迫就是论事,你要1我给你1,我都不敢怎么想会不会有2,3。这种情形下,分析设计只能是理论层面的了。唉。

banq
2011-06-22 09:44
对于OO上面我们通常有一个误解,觉得OO是一门比数学算法数据结构还要高深的知识。

其实完全相反,OO小学生只要有形象思维就已经具备,是一种天然的认识观,因此是无需要学习的,国外为什么大学不学OO,因为他们觉得在大学学他们小学都知道的方法论很可笑;

我们中国的计算机教育是参考国外大学,所以我们也没有教OO,可是关键我们的小学就开始灌输孩子所谓数学数理思维,而音乐绘画等孩子喜欢的象形等类似OO思维就没有培养。

最后,当我们再使用国外发明的软件系统时,包括架构和语言,会发现我们非常不适应,甚至都不会使用孩提时代的形象思维了。

IceQi
2011-06-22 10:44
2011年06月21日 17:52 "@gaofangjian"的内容
现在很多时候,我都是被迫就是论事,你要1我给你1,我都不敢怎么想会不会有2,3。这种情形下,分析设计只能是理论层面的了。唉。 ...


客户的需求从来就没有变过,问题在于绝大多数的时候我们都没有发现用户到底需要什么。软件的抽象需要基于用户最原始的需求。

用户描述:我要向给领导请假
不适当的抽象:下层人员要向上层人员发请假
适当的抽象:某人要向另外的人发申请,这个申请成立的条件需要按照某些条件过滤

Tyotann
2011-06-23 09:35
2011年06月21日 17:52 "@gaofangjian"的内容
没有OO我们的软件世界的问题有这么严重么?
面向过程编程存在了这么久,现在还继续的很好的活着。 ...


我现在在参与一个重构,公司很多人都是面向过程的,其实我对OO与过程没啥感觉,只要能写出简练、易于维护的代码就行了
但是不可否认,你用OO是较容易写出此类代码(即使刚毕业的,只要告诉他如何写就能依葫芦画瓢了),而且用OO,能很好的利用架构来做很多事,能利用OO特性节省很多重复代码。同时用OO能更好的来建模,建模后能更好的实现,AOP等特性又较容易的实现很多非业务控制。
但你用过程式的,只有多年经验且有心写好代码的才能写出能简单维护的代码,当你看到3k多行的procedure与一大堆重复copy的代码时,你蛋疼不?有木有?有木有!

[该贴被Tyotann于2011-06-23 09:40修改过]

gaofangjian
2011-06-24 12:21
面向过程会让人陷入一张无边无际的网,从每个端点起沿着过程路线走下去,不断地分支重复,到了最后的终点,回头看看来路,
发现已经迷路了。在面向过程中我们基本看不到参与者,更多的是一个个根据经验总结出来功能模块。一般是先梳理出业务的流程是什么,然后按照流程第一步做什么,产生一个功能,第二步做什么,又产生一个功能。
面向对象把我们置身于一个个有独立思想/独立功能的对象实体之中,在不同的场景下每一个对象展现自己特定的角色特点,在固定的场景下大家用互相理解的语言进行交流,
最终的得到一个结果。这样我们在分析的时候,首先会想到有多少个参与者,有多少个场景,场景下的规则是什么,场景下的角色是什么,
当然还需要一条主线把各个场景串联起来,形成一个完整的故事。

这是我理解的面向过程和面向对象两种思想,面向过程,感觉很机械,顺序下来,理解和使用起来容易上手,同时后续的设计、开发比较容易,
但是难于维护,因为你面对的是没有任何感情的网。面向对象,很生动,对象是有血有肉,我们在分析的时候能够像讲故事一样在述说。但是
就像板桥老师所说的,这是一种感性的形象思维,学理工出身的天生教育上就缺少这方面的培养,现在都退化了,这就导致很难在大范围的分析师、设计师、程序员
展开,也就是工程化比较困难。后期的维护性上会好一些,因为我们当初的系统就是按照故事的模式编排的,相对一张网而言还是更好理解一些吧。

一家之言

showerxp
2011-06-24 21:25
用户描述:我要向给领导请假
不适当的抽象:下层人员要向上层人员发请假
适当的抽象:某人要向另外的人发申请,这个申请成立的条件需要按照某些条件过滤
====================
既然提到这方面的内容,我就絮叨一下,把故事补全。

……
问:请问您是?
答:我是单位老大?
问:关于请假方面……
答:(还没有问完)是的,软件能让我知道所有员工的请假信息。
问:请假信息包括什么内容?
答:当然是谁请假,时间,事由什么的。
问:所有员工都要向你请假?
答:当然不是,直接向他们的主管请假,但是,我要求我都能清楚的知道详细内容。
问:主管是谁?主管要请假呢?
答:主管,其实主管就是我几个部门的负责人。主管请假要问我。
问:“问我”是指向我提出申请吧?
答:是的。
问:既然是申请,那么也就是批准于不批准的情况吗?
答:是的。
问:需要将批准与否反馈给申请者吗?
答:是的。
……
问:以上我问的问题你有什么问题吗?
答:暂时还没有。
问:以上我问的问题你是不是最适合回答的人选?或者有更适合回答这些问题的人吗?
答:关于请假方面更详细内容可以问主管。
问:除了请假信息你需要了解,还有什么你特别关注,特别是类似向你申请的事情。
答:有,单位印章使用也是我需要了解的,确切的说,只要我能批准印章的使用。
问:哦,那么印章是怎么个使用呢?
……


根据以上内容,得出以下抽象内容:下级向上级发出申请,上级决定批准与否,并反馈下级(涵括请假和印章使用等业务模型)。

我觉得,软件建模的乐趣,也是重点所在——对于具体业务模型进行了解,归纳,抽象,建立软件模型。而不是总在抓住某些建模理论死角费尽周章寻找合理解释。又如,本论坛讨论很多的图书馆例子,我认为核心业务——借书、还书,可以简单抽象为:某种图书对于图书馆仓库的出库入库。比如,新进书就是入库,销毁书就是出库,借书就是库存减一,换书就是库存加一。核心类就是图书馆仓库类,书种类。

gaofangjian
2011-06-25 22:08
我觉得,软件建模的乐趣,也是重点所在——对于具体业务模型进行了解,归纳,抽象,建立软件模型。而不是总在抓住某些建模理论死角费尽周章寻找合理解释。又如,本论坛讨论很多的图书馆例子,我认为核心业务——借书、还书,可以简单抽象为:某种图书对于图书馆仓库的出库入库。比如,新进书就是入库,销毁书就是出库,借书就是库存减一,换书就是库存加一。核心类就是图书馆仓库类,书种
=============
您观点我很认同,这更像是进一步的抽象,就像《分析模式》一样,讲的是在具体的业务模型上进一步的抽象。

这种抽象应该不是每个人都具备的吧,最近一直在和朋友讨论,有没有一种很自然的建模方法,让我们尽量减少经验的参与,能不能自然而然的推导出结论,一直没有找到。

IceQi
2011-06-27 19:09
2011年06月24日 21:25 "@showerxp"的内容
根据以上内容,得出以下抽象内容:下级向上级发出申请,上级决定批准与否,并反馈下级(涵括请假和印章使用等业务模型)。 ...


这个过程我也体验过,还有后续。。。。

。。。。。。。。
用户:请假需要有代理人
我:哦
用户:代理人需要确认代理,代理期间如果出现问题需要2个人负责
我:哦
。。。。。。。。
用户:3天以内的请假需要主管核准
我:哦
用户:3-5天的请假需要经理核准
我:哦
。。。。。。。。
用户:5-10天的请假需要总经理核准
我:哦哦哦哦哦哦哦哦哦哦哦哦哦
。。。。。。。。

表面上用户的需求总是在变,时时变,日日变,常常有人在抱怨用户的改变。换个角度,抽象一下用户的实际需求,他曾经变过没有?还是我们本来就没有看清楚他需要什么。如果用户都能说明白,那我们有什么价值呢。

软件是抽象需求的艺术。

jdon007
2011-06-27 21:37
1)“请假”这个业务基本不会变化的东西:
“要请假的人”向“负责审批的人”发出请求,“负责审批的人”进行响应。请求的内容(请假条):某人某时因某事请假若干天时间。响应的内容:同意或不同意。

2)“请假”这个业务会发生变化的东西:
至于怎么发出请求,这个容易产生变化,比如除了本人亲自填写,别人也可以代写,甚至可以先口头说一下,事后补登记。
还有怎么进行响应,也容易产生变化,可能根据请假的天数要求不同级别的人来审批,也可能根据请假者的不同职位要求不同级别的人来审批。

但不管怎么样,“请求”与“响应”的内容是基本不变的,发出“请求”和进行“响应”的人,可能会产生变化,此时可以设计出两个角色“请求者”和“响应者”来支持这种变化。我们用这些相对不变的东西来对抗变化。比如上面,出现根据不同请假的天数,由不同的人来审批的需求时,可以采用“责任链”模式进行重构或设计。

在图书馆借书、还书的业务场景,我认为不宜抽象为书的入库、出库。毕竟这与图书馆购买新书的业务场景,有显著的区别。借书、还书的业务场景重点要去描述的不是图书馆少了还是多了几本书,而是谁何时借了哪几本书,谁何时还了哪几本书,根据图书馆的规章制度(业务规则),要怎样进行处理。

找出需求中相对稳定的东西,比较难。有一个可以尝试使用的技巧,就是在考虑业务时先将用户“排出”在外。比如IceQi的例子—用户描述:我要向给领导请假。我会先考虑什么是请假,考虑请假中什么是不容易变化的东西,比如请假条、批准条;接着考虑到参与请假这个活动的人非常多变,此时就有必要进行抽象出“请求者”和“响应者”两种角色,来包容各种各样的“用户”。

抽象的本意就是从多个具象中提取出不变的东西,可以称之为共性。最开始,我们无法确定什么是不变时,不必急于抽象和设计,这往往会弄巧成拙,不妨在需要重构时再进行抽象,因为此时我们可能会比较容易觉察出哪些东西不变了,也就是有了对抗变化的必要基础了。

觉得showerxp和IceQi说的用户故事蛮有趣的,乐于参与其中。但抽象也不要把业务核心特征都给抽调了,比如showerxp将借书、还书的等基本特征都从业务模型中抽离,我个人是觉得不妥。

抽象的力量,不容否认。但不恰当或过分的抽象,很容易把自己搞糊涂,有限的智力再也无法应付。就像真理再进一步,可能成为谬论;抽象偏差了或过分了,我们可能就开始变傻了。

Edsger W. Dijkstra说得非常好:"The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise." Edsger W. Dijkstra, "The Humble Programmer", October 1972

showerxp
2011-06-27 21:52
2011年06月27日 19:09 "@IceQi"的内容
。。。。。。。。
用户:请假需要有代理人
我:哦
用户:代理人需要确认代理,代理期间如果出现问题需要2个人负责
我:哦
。。。。。。。。
用户:3天以内的请假需要主管核准
我:哦
用户:3-5天的请假需要经理核准
我:哦
...

那就可以抽象为:下级向上级发出申请,上级“根据某种规则”决定批准与否,并反馈下级(涵括请假和印章使用等业务模型)。

这样的抽象结果只是在原有基础上稍微做修改。其实迭代开发的意义就在这里——捕获需求过程总是由浅入深,当我们更深入的了解需求后,软件设计的模型只是在原有基础上稍作修改。如果原有模型不够抽象,“稍作修改”的过程很可能就是痛苦的推导重来。

showerxp
2011-06-27 22:24
:)我只是就实际业务做一些有限的想象。真是情况很可能不是这么一回事。

至于图书馆,我强调的是核心业务抽象成进销存,并不排除还有其他成分需要考虑。当然,根据实际情况很可能把图书馆系统抽象成一种类似进销存过程是不正确的。但是,如007说的“谁何时借了哪几本书,谁何时还了哪几本书,根据图书馆的规章制度(业务规则),要怎样进行处理。”这样的需求,我的所谓图书馆进销存系统只需查询“出入库者”、“出入库时间”、“出入库清单”等,并根据用户需要设计“出入库规则”即可满足。我看不出007所谓的“在图书馆借书、还书的业务场景”与“图书馆购买新书的业务场景”之间,有哪些显著的区别。除非你能提出具体的需求使得我得出的出入库抽象需要彻底推翻。:)

至于007后面的言论,由于缺乏具体论据,则不好评论,亦不敢苟同。

[该贴被showerxp于2011-06-27 22:25修改过]

IceQi
2011-06-28 09:49
2011年06月27日 21:37 "@jdon007"的内容
The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise ...


很精准的,抽象必须在一个限定的应用环境内。过度编码、过度设计,这些都可能会带来麻烦,过度抽象的恶果会更加的丰硕。

在请假的活动中我更倾向于“请求” “响应”描述,另外还需要增加“规则”。请假的全过程很多时候并不限于上下级间,同级的人员间也会出现,另外如代理等临时状况也会发生。如果出现了上下级的定义那么临时作为代理的人员也必然被描述为“上级”,但很多时候系统中有些事务又不能由这样的“上级”执行,从而上级又会衍生出多种类型,运行时又要理解上级的类型。显然这种程序对于对象的理解是人为刻意增加的,不一定适合。我这么说也是仅限于我们前面提出的用户需求。


这些是我们工作中非常熟悉的应用,比较容易讨论。图书馆这样的业务过程可能大家都不熟悉,具体的内容主要都是臆想。当我们对于事物本身没有彻底了解的时候很难想象刻意提出正确的抽象,我觉得这个只能用作说明不好做深入的分析。

jdon007
2011-06-28 19:19
图书馆业务基本都会涉及到图书的入库、出库等基本操作,但入库、出库操作作为描述“借书、还书”场景的“业务语言”, 不感觉有点“绕”吗?

有些有多年开发经验的人常会说业务不就是“基于一定操作规则的增删改查”(这里变成基于出入库规则的入库、出库),这没错,可是这种描述缺失了“业务语言”。“增删改查”只是基本操作,就像“加减乘除”一样,但用来描述要解决问题的思路或设计方案,合适吗?“增删改查”式的抽象也许可以描述所有业务,甚至非常适合描述一些业务,但更可能出现的情景是其会模糊甚至抹掉本应清晰、直观的业务信息。

当然这也只是个人之所见,仅供讨论。