通过“库”来实现业务,可能会引发业务系统之间耦合,需要通用业务服务化,将通用业务下沉,详见《小小的公共库,大大的耦合,你痛过吗》。
通过“join”来实现业务,可能会导致数据库之间耦合,需要基础数据服务化,实现数据库私有化,解除数据库之间的耦合,详见《小小的数据库,大大的耦合,你通过吗》。
但如果服务化不合理,将部分个性化业务下沉到了底层,耦合与瓶颈会更加严重。
场景还原
业务1,业务2,业务3,因为join导致数据库实例耦合在了一起。
为了实现通用数据库table-user的解耦,实施了服务化,将通用user数据的访问抽象出了服务。
由于服务化不合理,会有很少很少的个性化业务逻辑,实现在底层的服务中,典型的伪代码是:
switch(biz_type){
case(1) : exec_logic1();
case(2) : exec_logic2();
case(3) : exec_logic3();
default : exec_default();
}
为什么会引发耦合呢?
不妨设,业务1来了一个新的个性化需求,这个需求本来实现在业务1自己的代码里是合理的,但工程师S想到,底层的通用服务里也有业务1的一小撮个性化代码,评估后,发现实现在底层新的需求改动的代码最小,时间最短,于是来找底层服务的负责人工程师B。
遗留了不合理的代码,就会有第一次妥协,妥协了业务1,就会妥协业务2,随着时间的推移,底层服务越来越复杂:
直到有一天,底层服务出了一个小bug,影响了业务1,业务2,业务3,历史总是惊人的相似:
额,然而,这个理由,好像在大boss那解释不通…
如何解耦呢?
业务代码上浮,通用代码下沉,服务化彻底。
解决方案并不复杂,分层架构中,每一层都有自己的职责,每一层都应该守住自己的底线。
启示
一、讨论技术方案时,不要总以:
“放在你那边做代码少”
“放在你那边做时间短”
作为设计折衷的理由,而要多问:
“怎么做合理”
二、尽量杜绝底层出现switch case(biz_type)走不同分支的代码。
业务代码上浮,通用代码下沉,服务化彻底,只是一个很小的优化点,但对于底层服务解耦却是非常的有效。