1.背景
某API项目,项目天然地按业务分为了不同的包,那么每个包都独立处理自己的业务逻辑,独立接管数据源,独立地向外部提供数据,彼此基本互不通信。
不过,随着需求的增多和业务的堆积,项目的复杂度越来越大,但是每个独立模块却又不足以独立出去成为一个单独的项目,而模块间又因业务需要开始发生交互的时候,问题来了。
2.问题描述
由于模块间的数据交互,按照Spring的套路,是可以直接把容器接管的对象注入到你需要的地方去的,那么一旦你开始问其他模块要数据,开始要命了。如上图,如果模块3问模块2和模块4要数据,理论上来说,他是不是可以随意注入这两个模块的各种服务呢?
答案是肯定的。这个时候你会发现一个问题,由于本来在一个模块内某个数据源可能经过多重必要的封装再提供接口数据的,但是其他模块他并不知道这一点。于是他极有可能注入数据源在封装的过程中各个阶段的服务类,也有可能直接注入了最底层的数据接口,他再去做自己的逻辑处理去自己封装一遍。这样,漫天飞舞的入侵完成了,这个地方飞满了各种各种的花蝴蝶,简直眼花缭乱,一片失去控制的景象。
3.解决思路
这个时候笔者想到是否可以把某个模块的各种数据服务聚集到一个服务中去呢,对外部(其他模块)来说,约定好只允许调用我这个公共的服务接口,我对外部屏蔽掉所有逻辑,你外部也不用关心我的数据怎么来的,你只要问我这个接口要数据即可。如上图所示,
到此问题基本可以解决,优缺点也在图中描述了。
4.深入
接着,笔者发现其实这个设计思路,类似于门面模式,或者说就是门面模式。网络上找来了门面模式的意图:
- Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
- 对子系统中的一组接口提供了一个统一的接口。门面定义了更高层次的接口,使子系统更容易使用。
- Wrap a complicated subsystem with a simpler interface.
- 以简单的接口包装复杂的子系统
可以看到,笔者文章中所说的可以被视为是门面模式的一个应用场景,虽然不是系统级别的交互而只是模块之间的交互,但是笔者相信这样去设计至少在接口的易用性和模块间的解耦程度上,是可以做到有所提高的。至此,门面模式get。
维基百科传送门:https://en.wikipedia.org/wiki/Facade_pattern