谈到生命周期这个问题,其实非常容易理解。人的生命,理论上讲有百年,或者说人的生命周期是一百年。但是做为人的一个独立个体,其本身的生命有长有短。“或华发以终年,或怀妊而逢灾”,所以如果要做一个人的生命周期管理的系统就得具体的控制每个个体实际的生命周期的不同。
说直白一些,在软件系统中,生命周期就是就是一个实体对象存在的整个过程即从创建、产生、运行和最终消亡的过程。
在DDD领域驱动设计中,生命周期的管理是一个重要的问题。设计出来的模型如果不能和实际的对象的生命周期一致,就会让人产生一种怀疑,这种怀疑其实就是整个设计出现了问题。MDD中,生命周期和模型的元素是有着紧密的联系的,所以在对待生命周期的管理上一定要慎重仔细。
生命周期的管理可以从三个模式在不同层次上进行控制:
1、聚合和聚合根(Aggregate,Aggregate Root)
AGGREGATE(聚合),它通过定义清 晰的所属关系和边界,并避免混乱、错综复杂的对象关系网来实现模型的内聚。聚合模式对于维护生命周期各个阶段的完整性具有至关重要的作用。每个AGGREGATE都有一个根(root)和 一个边界(boundary)。边界定义了AGGREGATE的内部都有什么。根则是 AGGREGATE所包含的一个特定ENTITY。
上面说的有些抽象,其实在软件设计中有“高内聚,低耦合”这个概念,其实就是尽量减少软件模块或者层次间的无谓的交互。延展到生命周期管理,同样如此,如果一个模型最终只抽象到只有一个聚合实体,那么生命周期的管理会不会非常简单。当然,这只是一种状态,一般来说,还是会有N个实体的,但是如果这些对象能通过某种最小的规则形成一个聚合体,这个聚合体中有一个主要的实体来实现和其它聚合体的交互,那么是不是对于生命周期的管理来说,相对容易很多。
具体而言,假如有一个班需要管理,一般来说,很少有人会针对每个人进行管理,都要建立一个班长,做为对内外的信息输入输出的接口。而如果这个班只有一个人呢?就犯不着建立一个班长了。
所以说,聚合的目的(包括聚合根),就是将生命周期的管理简单化,安全化。它有下面一些特点:
a、一个聚合只有一个根和边界;
b、聚合内部对象可以互相引用,但对聚合外部的交互必须通过聚合根即聚合根是外部访问访问本聚合体的接口;
c、聚合根代表了聚合本身,其它内部对象只对内部标识负责,它们只从属于本聚合;
d、聚合根是对外交互的唯一接口并负责维护相关的业务规则;
e、聚合内部的对象可以可以引用其它聚合的聚合根;
f、聚合内部对象和聚合根是原子的,即删除要全部删除;
2、工厂(Factory)
设计软件时,有时候儿会遇到这类问题,一个对象的应用场景和实现比较复杂,那么就可以通过以工厂的设计模式来实现,同样,在DDD中也是如此。在实际的生活中,把同样一件事情交给不同人去做,产生的结果很大可能不一样。但是如果把做事的过程交给一个人,然后大家把相关的需求交给他,由他来实现,那么结果大致相同。明白了这个道理就明白了工厂的意义。再比如不同的木匠,打造一个同样的桌子,很可能大小,形状和颜色上都有不同。但如果交给一个家俱厂来做,通过标准的机器来生产,那么这种现象的差异会让人感觉不出来。
每个人对业务规则的理解和对实现一个实体的过程都有各种的不同,甚至可能是完全相反的理解。所以在软件设计中很容易产生一些沟通的成本。而对于生命周期管理来说,更是会产生生命周期的控制过程的不同,那么这就会导致设计上的无法正确匹配(想象一下,别人还没有创造对象就开始引用的后果或者引用已经释放的对象的后果)。所以这里需要像上面提到的工厂一样,把实体对象的生产抽象隐藏起来。让生命周期一开始,就处于谨慎的保护之中。这既可以防止内部业务逻辑的外泄,又可以降低应用层的负担。
“辛苦我一个,幸福千万人”,这就是工厂的无私精神。
3、仓库(Repository)
生命周期有创建,有运行,那么还有销毁。销毁有可能是直接就废弃回收了,也有可能是被持久化到了数据库或者其它形式的本地存储。所以这就需要创建一个Repository来存储这些生命周期结束的对象,因为谁也不知道,什么时候儿会把这些对象重新生成创建出来。进入仓库的一定是聚合,想想前面提到的原子的说法就可以明白是怎么回事。仓库为了更好的为外界应用服务,一般会分成定义和实现两个部分。举一个实际的例子,在数据库的访问过程中,一般是通过SQL语句这个接口来和外部沟通,数据库本身就会有元数据的定义和实际数据存储两个部分。但是仓库一般是不处理事务的,通常会交给工作单元(Unit Of Work)来操作。仓库的接口,一般会有规则定义的使用,这个在有数据库操作经验的人非常容易理解。
从上面三个部分可以看到,DDD中对生命周期的控制还是从点到线再到面,从小到大逐一展开。学习设计的难度不在于理解每个概念和每个语句,难在把设计的思想和实际结合起来。但是,如果一个从来没有写过程序或者只写过很少的一些程序的人,让他来弄通这些设计思想和设计理念,难度是有多大。就好像一个小孩子,他知道刀法的使用口诀,但他的力气都不足以拿起一个刀把儿,那么,结果就可想而知了。
生命周期在实际运行中是相当复杂的,特别是在大型的系统中。那么在设计时既要保证在整个运行过程中的实体对象的生命周期的完整性,不能够随便回收或者置之不理;也不能因噎废食,执着于设计一个复杂的生命周期系统,结果异常难于扩展和维护。所以如何把握一个MDD模型中的各个实体对象的生命周期的具体情况就必须有一套正确的控制方法。正如一些纪律和规则是维护一个团体完好运行的前提,软件设计也是一样。
软件只是一种系统, 不是超出人的想象之外的东西,它必须服从于人类大脑抽象设计的规则。