记得初中的时候,有阵网吧查得特别严,规定未成年人不能入内,需要身份证原件或复印件验明真身。 我那时还不到年龄,在007的启发下,复印了自己的身份证,把复印件改大了两岁,再复印了一份淡化修改痕迹,大摇大摆地走进网吧,结果被赶出来了。 我怎么会知道早我两年出身的人的身份证只有15位呢……
最近接手的一个遗留项目要上线了,也发现了一件和identity有关的趣事。 该产品的终端用户可以通过产品的UI管理一种业务对象,我们假设它叫Foo。 产品内部集成了一个第三方系统,在两个限界上下文中存在一对映射关系,即每个Foo都对应该第三方系统中的一个对象Bar。 在试生产环境中,终端用户已经把上线时需要的数据都录入好了,在之后的测试中也一直运行得不错。 现在生产环境已经安装完毕,为了减少终端用户的工作量,我们试着导入试生产环境的数据,结果发现了意想不到的问题: 生产环境中Foo和Bar的对应关系失效了!当用户编辑Foo并由此借修改Bar时,系统总是提示找不到对应的Bar。
最后问题被找到了,该第三方系统的导出功能并不会导出Bar的identity,其导入功能会原封不动的恢复导出的数据,但是id除外! 它会根据内部规则生成一个新的id,因此原先保存的对应关系失效了。 我们编写了一个小脚步为生产环境修复了这个问题,但是有一个小细节引起了我的注意。 有几个编辑Foo的功能,其底层并未交互第三方系统,但也神奇的失败了,提示找不到对应的Foo。 原来虽然Foo有自己的id,但是所有操作的Foo的功能实现,从UI到底层都在使用Bar的id作为标识……
在这个例子中,Bar的id虽然也是全局唯一的,但并不适合作为识别Foo的标识,因为它只是实现Foo的技术细节,最好尽可能地隐藏这个概念。 尤其当这个标识是开发组织不可控时(比如由购买的第三方产品管理),它可能因为一些意想不到的原因而改变。 虽然通过数据变更脚步可以修复问题,但是如果这个标识被传播到了系统的各个角落,修复的难度和风险就大大增加了。 因此,只要有可能,id最好由自己把控,可别为了图方便而借用他人的。
但这并不意味着每个系统都一定要自己搞一套id,比如一个企业可能将业务分解到有若干的子系统中,那是不是每个系统都需要建立自己的用户id呢? 显然这是不必要的。我觉得只要产生id的系统组件是开发组织可控的,并且所有团队都能达成使用该identity的共识和约束,那借一借也无妨。