架构师的十八班武艺:架构边界
在我们日常的架构活动中,总会面临各式各样的架构边界问题需要决策:这段逻辑是放在哪个系统?这个外部渠道的接入是否需要进过金融域?这个服务是由上游还是下游来定义?架构边界如果决策的不合理,会对应用系统的可延展性、稳定性、复用性等造成不可逆的伤害。
对于架构边界的决策,我们需要遵循如下原则:从模型出发、不徒增实体、模型边界看权衡。
首先,架构的边界往往就是模型的边界。这里的模型指的是领域模型。定义一个应用系统,首先需要定义系统的核心模型,同时核心模型的明确也就意味着系统对外服务的明确。比如对于用户域,我们如果明确了基本的用户模型,同时定义了 4A 模型之后,对应的对外服务也就清楚了:无非就是用户信息的 CRUD、认证、授权、鉴权。超出这个范畴的,就不是用户域需要提供的能力,就不在用户域的架构边界内。
其次,基于最简化原则,如果引入某个域没有增加能力,就不要引入。例如,对外部渠道的调用,到底要不要经过金融域的问题。首先,我们看一下金融域的主要职责:对于外部渠道的抽象,将外部渠道的复杂交互抽象成内部的统一交互模式;同时提供幂等、超时查询/重试等异常处置能力。如果我们是接入一个卡渠道,其中包括 3DS、auth、capture 等原子能力需要封装,那经过金融域是合适的。但是如果我们只是接入一个简单的短信渠道,渠道就一个服务,同时也没有啥查询/恢复能力,就没必要教条的经过金融域去和渠道交互。如果接入的是一个政府提供的认证渠道,那要看金融域是否抽象了认证的标准内部模型,如果有,大概率可以过,如果没有在快速接入的背景下也可以不过,交由架构演进去解决。
最后,即使完成了上述两类的决策,往往还是有一些模型边界的问题无法决策。基于 DDD 的理论,两个领域模型之间,都会存在模型映射的问题。这个模型映射是在服务调用方还是服务提供方来进行,往往是架构边界讨论中非常纠结的一个点。这类的决策没有标准答案,只有一些实践的原则。
对于越标准的领域服务,倾向于由上游去进行模型转换。例如账务域,就应该提供标准的复试记账服务,由上游的资金服务域系统将不同的业务行为翻译为记账科目,调用标准账务服务完成核算工作。
对于越核心的系统,尽量减少模型转换。比如对于支付系统发送短信给用户的场景,一般的做法都是支付域发送统一的支付成功消息,由于通讯域去理解支付成功消息并完成到短信模版的转换。
对于标准数据字典到领域内概念的映射,由服务提供方执行。比如对于外汇域,一个重要的概念是买卖方向(BID/OFFER),是由卖出币种是否等于标准币种对的标价币种决定。标准币种对和买卖方向的概念,就应该收入在外汇域内部,对外只暴露买入/卖出币种两个通用概念。
这些实践原则还可以罗列很多,这里不再赘述。在日常工作中可以采用英法体系的做法,采用判例法,基于相似 case 的做法推导出通用的决策逻辑,并形成 Architecture Repository。
版权声明: 本文为 InfoQ 作者【agnostic】的原创文章。
原文链接:【http://xie.infoq.cn/article/39a2578d49f396fbbd4b8e8ce】。文章转载请联系作者。
评论