别再被“共享”骗了!上下文混用才是系统崩溃的元凶

共享常被视为提效手段,实则因忽视上下文差异而制造混乱。真正高效源于清晰边界与安全集成,而非强行共用资源。


“共享”其实是个伪命题!

共享是一个伪命题   本来两个不同的Context上下文,非要共享一部分,这样本来是为了资源共享、代码重用,表面上提高生产力和节约杜绝浪费,其实增加了复杂性,甚至导致冲突。

只要涉及到人的任何事都存在共享伪命题,例如中餐一起吃饭,大家共享一桌饭菜,其乐融融,其实背后真相令人唏嘘,有的人爱吃的多吃了,不爱吃的少吃了,有的担心浪费把别人不吃的都吃了,造成每个家庭成员的每顿饭营养都不均衡,所以,在家分餐制能保证每个人营养到位,家里有两个以上小孩最后发现还是分餐更适合,为什么成人要合餐呢?这是身陷上下文陷阱而不自知。

在工作中也有这种共享情况:两个团队共享一台复印机,共享一个咖啡间,共享一份代码库、共享一个数据库,但是之所以是两个团队,就是因为不同上下文Context划分了两个团队,各自有各自的特殊情况,结果当这些身处自己特殊情况上下文的团队其使用共享资源时,无疑下意识根据自己习惯去使用,这是正常不自知成本。

结果,共享资源被几个团队修改得乱七八糟,然后契约和权威大棒开始大行其道,每个团队战战兢兢使用共享资源,这增加了团队压力和认知负担。

所以,共享上下文本质上是多个不同上下文将其通用部分抽象出来共享,但是这种抽象通用的思考前提也是有上下文前提,也是基于一种上下文情况角度发现它们是通用,时过境迁,这种角度的前提上文如果发生变化,你的通用抽象就没有效果。



衍生通读版

"共享"听起来很美好——资源共享、代码复用、节约成本、提高效率,但现实往往骨感得让人想哭。尤其是在软件开发、团队协作甚至家庭生活中,强行把两个本不该混在一起的“上下文”(Context)硬凑成一个“共享”的东西,最后不是效率翻倍,而是混乱翻番。

先说个生活中的例子:中餐合餐。一家人围坐一桌,热热闹闹,看起来其乐融融,对吧?但你细想一下:谁爱吃肉谁多吃两块,谁不爱吃青菜就干脆不动筷子,还有人怕浪费,把别人剩的全塞自己碗里……结果呢?每个人的营养摄入严重失衡。家里有两个以上孩子的父母,最后往往发现:分餐制才是王道!每个孩子吃自己该吃的,营养均衡、不争不抢。那问题来了——既然孩子分餐更科学,为什么大人还要坚持合餐?因为习惯,因为“看起来和谐”,但这种和谐,其实是“上下文错配”的假象。

再看职场。两个团队,明明业务不同、节奏不同、目标不同,却被要求“共享一台复印机”、“共用一个咖啡间”、“共用一个代码库”,甚至“共用一个数据库”。听起来是为了节约资源,但你想过没有:他们之所以是两个团队,正是因为他们的“上下文”完全不同!每个团队在使用共享资源时,都会下意识地按照自己的习惯和需求去操作——这不是自私,而是人性。结果呢?复印机卡纸没人修,咖啡间堆满没洗的杯子,代码库被改得面目全非,数据库字段谁都能动,最后系统崩了,锅却没人背。

这时候,管理层开始祭出“契约”和“规范”——谁动共享资源必须写申请、必须走流程、必须签字画押。于是,原本为了“提效”的共享,变成了“提压”。每个团队战战兢兢,生怕动了别人的东西惹麻烦,协作成本飙升,创新动力归零。这不是共享,这是枷锁。

问题出在哪?出在“共享上下文”的幻觉上。很多人以为,只要把多个上下文中的“通用部分”抽出来共享,就能实现复用。但别忘了:所谓“通用”,本身就是基于某个特定上下文视角的判断。今天你觉得这两个模块都能用同一个用户服务,是因为你现在的需求视角如此;明天业务一变,这个“通用服务”可能就成了绊脚石。更可怕的是,一旦多个上下文强行共享一个模型,任何一方的变更都可能破坏另一方的逻辑,最终演变成“牵一发而动全身”的技术债务泥潭。

这正是领域驱动设计(Domain-Driven Design, DDD)反复强调的核心原则之一:不同的业务上下文,必须有各自的模型边界。你可以通过“防腐层”(Anti-Corruption Layer)或“端口与适配器”(Ports and Adapters)来实现安全交互,但绝不能直接共享内部模型。就像两个国家可以贸易往来,但不能共用一套法律——否则,迟早乱套。

说到这里,不得不提本文思想的源头:埃里克·埃文斯(Eric Evans)。他是《领域驱动设计》一书的作者,被誉为“DDD之父”。他在2003年首次系统提出“限界上下文”(Bounded Context)的概念,彻底改变了人们对复杂软件系统建模的认知。他指出:大型系统不是靠“统一模型”成功的,而是靠“清晰边界+安全集成”成功的。真正的复用,不是代码复用,而是概念复用;真正的共享,不是资源堆砌,而是契约清晰。

回到现实。如果你正在开发一个模块化单体应用(比如用Spring Boot或NestJS),千万别为了“省事”让多个模块共用同一个数据库表或实体类。每个模块应该有自己的数据模型、自己的业务规则,通过定义清晰的端口(Port)暴露能力,再由适配器(Adapter)对接外部。这样,即便未来某个模块要独立拆分成微服务,也能平滑迁移,毫无痛感。

总结一句话:共享不是目的,解耦才是智慧。强行共享,只会制造隐形冲突;尊重边界,才能真正高效协作。