从“贫血”和“充血”说起

08-11-29 IceQi
从“贫血”和“充血”说起

这两个词对我来说也是很新鲜的,看看我在Jdon的注册日期也就是从那时候开始才有所耳闻的。这两天看到有人在讨论于是整理了一下思维。

看到网络上很多的讨论中对于充血和贫血的看法往往是以绝对的方式进行描述,都是用类似“不是。。。就是”的方式进行修辞。我个人的理解在实际的应用环境中是很难出现这种“不是。。。就是”境地,特别是在进行设计的过程中。贫血和充血应并不只是两种思考的方式更多的应该把这两种思考的方式放在我们所需要的实际情况下进行权衡,这样才有比较的意义否则就好像在争论“土豆和白菜哪一个比较好吃”一样的没有意义了。正确的方式是应该设定一个应用场景,比如:在xxxx项目中当我们描述从图书馆借书的过程时,“书”这个对象是充血还是贫血更合理呢?脱离了实际应用场景任何讨论都是没有意义的因为大家都是站在各自不同的立场上,各自的解决方案所面对的问题域也是不尽相同的,同样是一个“书”类型在书店系统里面和印刷厂系统里面承担的职责显然有着本质的区别,此时不可能再用同样的角度进行讨论了。

在一个实际应用系统中,我们通常需要面对两个类型的对象“数据集”和“实体”,其中数据集承担的任务非常的简单就是作为一个传递数据的场所。比如一个A对象的创建过程中需要赋予一个ID,我们可以创建一个接口 A.setSessionId(Object instId),此时从业务的角度出发instId这个对象除了作为“id”的载体什么都不是只需要是一个“数据集”,显然我们对他也没有更多的期望,那么这个对象应该是贫血的了。那么换一个应用场景,假设A是一个游乐场的来客,instId是游乐场不记名、不挂失、同时提供支付功能的电子票,并且这个instId需要在多个系统独立且无法整合的游乐场间通用,那么这个instId需要同时承担了多种责任:唯一标示持票人(比如记录购票人的相片、年龄。。。等),与其它收支系统的协议适配,支付余额记录。。。。等等,此时这个instId就肯定不能是一个贫血的实现了。

无论是以何种方式实现都不能够脱离实际应用场景,脱离了应用环境任何讨论都是没有意义的了。

我还看到了一个发言:

我要查找一本书:

Book book = Book.Find(),“书去找书”,太别扭了。

Book book = BookManage.Find() , “图书管理员帮我找本书。”符合自然习惯。

发言者认为Book.Find()就是书的充血实现。其实这又是另外的一种错误了,本质上是没有理解00的含义或者没有切实的思考找书的业务过程。书怎么能去找书呢?显然索引书的职责应该是“图书管理员”或者“图书名录”承担的,而书本身只能提供章节和页数的索引功能。血是不可以乱充或者乱贫的,在中医里面有放血的疗法,在西医里面有输血的疗法,但这些都是有着严格的应用场景,如果输血的血型不匹配是会要人命的!!!

下面开始发散思维了。

大家都在热衷于讨论技术,这是好现象因为没有技术基础其他一切都是免谈的,但是更多的人似乎忘记了“为什么需要技术”这个关键性的问题。比如上面的例子中只是在考虑“贫血”和“充血”这些名词了,集中于考虑怎么去实现这样思想的表现形式,却恰恰忽略了思想的本质“为什么要充或者贫”。技术本身是没有任何价值的,一个技术再高的程序高手(暂且比如Banq吧,谁让他这的幌子呢)如果没有项目可作恐怕也要饿死了。现在的风气中绝大多数人都在热烈的讨论怎么做,用程序做出了各种各样天花乱坠的效果,可是如果忘记了自己要做什么所有的这些有没有什么根本价值呢?说句实话一丁点价值也没有。

很多人都在犯一个共同的毛病“空想”,没有时间、地点、人物、事件,什么都没有只是在思考一个结论。这样的思考是没有意义的,所有的思考都必须建立在一个特定的场景之上。举个例子,现在评价JiveJdon的时候首先要搞清楚一点,到目前为止这个实现都还不是一个完整的产品,更倾向于一个完成度比较高的Demo,因此我们不能过多的从配置的易用性和页面布局是否符合多数人的使用习惯这个角度去衡量,更多的讨论需要基于它的系统结构、实现方式等等,我们应该更多的讨论“他的数据和业务是否过于耦合”而不是“他的首页应该使用淡蓝色”。

程序员需要不只是技术,更需要良好的“有益思考”能力,首先我们要习惯思考进而需要习惯从正确的方向进行思考。任何技术都是会过时的但是思考能力可以永远跟上时代。在技术领域发展是一个不变的法则,今天是C++明天是Java后天谁也不指导会出现什么。昨天可能是比尔大叔的思想先进,今天有可能是Banq的更好一点,但是明天呢?没有人能够预言。我们今天学到的技术必定会在明天被淘汰,但是如果我们学到了思考进而分辨技术高下的能力那么就无论如何不可能被淘汰了。

    

banq
2008-11-30 19:51
我多年前就指出,其实如果真正掌握Evans DDD,真正做好实体和值对象,抛弃数据库编程思路,这个问题自然就豁然开朗。

之所以有那么多人喜欢讨论这个问题,实际上还是他们的数据库编程思路导致,数据库编程将对象看成数据的集合体,实际是一个大的数据结构。但是,对象不只是数据啊,还有操作行为。

数据库编程思路的人将这些操作行为都放到service等其他地方去了,这当然是 失血模型了。

不懂OO的有的还故作聪明:以为将所有行为都塞入一个模型就是充血了,他又不明白OO细分原则。

到底哪些行为应该放入模型中?取决于你实体聚合的根以及他们的边界和生命周期,这些都是DDD的要旨,不明白这个道理就永远是围绕数据式对象编程。

IceQi
2008-11-30 20:54
在这一点上同意你的想法,很多时候看到对于血型的争论实质上都是在围绕数据归属的争论,他们的核心还是在数据而不是站在业务或者对象的起点上。

软件是一个集合体,在整个的过程中必须从整体的角度进行考量,数据、操作、过程,不能够在任何一个方面有所偏颇。在设计的过程中一项重要的工作就是在进行平衡,如果缺少了对整体中任何一个方面的考量都会得出一个似是而非的答案,也才会有了这么多的争论。

banq
2008-11-30 22:01
我以前就说了:失血和充血只是结果,什么结果?就是你是否OO思维的结果。

过于执着讨论是否充血,就总是在一个结果现象上纠缠不清,好好掌握DDD,然后可以用这个结果来检验你掌握DDD的程度。

xmuzyu
2008-12-01 13:48
SSH想实现充血有难度。哎。。

猜你喜欢
3Go 1 2 3 下一页