关于暴露业务模型(Exposed Domain Model Pattern)1

关于暴露业务模型(Exposed Domain Model Pattern)
这个问题涉及到企业应用社区中许多流行了好多年的热门词:POJO,DTO(VO),FAÇADE。这个问题非常复杂,比贫血模型更易引起争论;其中由方法论层面上的问题,也有技术层面的问题,在这里也无法给出全面的分析,那就只能谈几点认识,可能带有一些倾向性,其实这类问题本来就有一个价值选择的问题。这些倾向和选择也都是缘于实际的体会。

我首先注意到一点,Exposed Business Model Pattern说法的出现实际上跟Domain Driven 以及 Model Driven有直接的关系,实际上它们之间也的确有内在的联系,可以这样说:Exposed Business Model Pattern使前者的驱动力量贯通所有的三个层。持久层集中反映模型的静态结构,业务逻辑曾集中反映模型的动态行为,那末,表现很自然地应该直接地去渲染模型,从这个角度看问题,应该承认模型暴露的基本合理性。这是其一。另外一点是,历史上DTO(VO)\FACADE模式在J2EE体系中的扩张,如果稍加留意就能看出,其根源很大程度上来自于某些技术的局限性(其中一些局限现在仍然存在),而随着领域驱动、模型驱动等方法论的深入以及一些技术、平台的发展,相当一些原因已经流失了。

从理论上说,在整体上,功能用例是模型的一部分,是模型作为一个有穷自动机时,在它全部的状态空间中,对于系统的外部使用者有价值的一些状态变化路径的集合,表现层所表现的是模型的一部分,也是模型的一个子集;在局部上,表现层的一个元素或者一部分元素所表现的也是一些完整的模型对象的一个剪裁;在各个方面都可以认为功能层、表现层是为模型开的一个窗口,通过它系统的外部使用者获得了自己的价值。说得形而上一些,系统的功能集合是系统用户的价值观作用于模型的结果。模型更完备,功能则反映了用户的价值取向。这几点是封装模型合理性的一个基本解释,实际上Façade层的各个Service也基本上对应着功能用例,DTO本身则是模型对象的剪裁。也就是说在封装模型中,系统地设计者为这个窗口安排了专门的一个层、专门的一套中间对象来形成这个窗口。

但是问题随之而来:如果这个窗口足够大以至于接近于完全暴露,这种安排必然就是多余的,最起码,过多的安排就是多余的,所谓过多的问题应该这样理解:这种安排是否应该导致一个独立的层的存在以及几乎与模型对象等量的DTO对象的存在。答案是否定的,根据如下:

模型并非是先于用户的价值需求而存在的,而且正好相反,因此模型在整体规模上不会超越功能集合:在系统性、完整性上优于功能集合,在尺度上基本是功能集合的外包络或者凸壳。也就是说,这个功能窗口必然使模型几乎完全暴露;从这个意义上,Façade和DTO只不过是另一个冗余模型而已
如前所述,因为功能角度和模型角度价值观的差异,在两者之间会出现一些转换环节;但是这些环节并不足以构成一个几乎与模型相等规模的冗余模型的存在的理由。
对于转换环节,理论上可以通过具体的技术层面的手段来解决,而不是方法论层面上的体系层面上的安排;实践上,这些技术手段也越来越多。
最后一点,最起码的,软件开发哲学中普遍适用的思路:折中,将中间冗余降低到最小。或者说,冗余模型应该被抑制。
另外一个在方法论上需要充分关注的一个要点是,冗余模型的存在会导致一些后果。模型驱动方法论的实质在于,在零散的、随机的、短视的用户需求和开发活动之间存在一个十分关键的中间概念模型,它更为理性,更为完备,它是对用户需求的总结和提升,它被用户需求所驱动,但又高于用户需求,即面向用户现实的需求,被这种需求所驱动,又面向用户未来的可能的需求,因此它对系统的可扩展性有决定性影响,是软件系统能够良性发展、进化的内在的根本保证。冗余模型的存在很大程度上弱化了核心模型的这个作用,开发者往往应一时之需,在冗余模型层首先实现了一些功能,核心层则没有相应的进化;由于冗余模型的必然的不完备性,模型驱动思想在这个环节上被阻隔。一个系统的行为(或者功能)和系统的结构应该是正交的、横切的关系,功能模块由结构组件协同工作完成,结构组件横切许多功能模块;功能模块是对系统的垂直划分,结构组件是对系统的横向剖解。如上文所述,冗余模型很大程度上与功能用例是对应的,其后果是,作为逻辑层的结构单元,它与功能模块之间是平行的关系。这是Service—DAO模式纵向分割系统的根源。

以上所述的各种情况实际上将冗余模型推上尴尬境地:因为它直接面向功能用例,其结构必然与功能模块平行;如果这种与功能模块平行的结构单元承载了实质性逻辑,则违反了结构-功能正交的一般规律;另一方面,冗余模型的存在又必然吸引开发和设计活动将大量的逻辑安排给它。如果它没有实质逻辑,只是一层很薄的封装,则根据上文的分析,它的存在的必要性就基本消失。所以,冗余模型的存在是一个悖论。

比较有意思,你讲的冗余模型 是不是就是所谓充血模型呢?

冗余模型存在是一个悖论,这个结论有些意思,我以前一直认为冗余模型存在分析领域,是一个设计概念,具体到代码,是可能有几个类组成的,这个概念我反复强调很多次,既然那么多人就这个简单问题来jdon讨论,有可能还是什么地方出了问题,也有可能这些老外提出了一个悖论概念。

从跟踪老外研讨多年自觉来看,如果一个很重要的概念在初期火热后,后面没有大规模普及,那么肯定是存在严重问题,因为一些致命问题一旦有人只要一句话点破,大家就心知肚明,再反复争论就显得自己固执和愚昧,这也是我们很难大篇幅看到老外一些概念遭否定的篇幅,而我们一直以为这个概念很先进而走进死胡同。

所以,不管国外软件比我们先进多少倍,我们不能没有自己的思考和声音,这是中国软件昌盛的根本。