2.2.2 创建共享库
创建共享库时,我们应该以极简为第一原则。如果你有第三方库的依赖,这是你要考虑的重中之重。假设我们的授权组件依赖于某个流行的Java库,譬如谷歌的Guava,并显式地声明了该依赖。Payment服务导入新的授权库时,由于依赖传递,它也会依赖谷歌的Guava库。到目前为止,一切都很顺利,直到Payment服务引入了另一个第三方库,新的库也对谷歌的Guava库有依赖,不过它依赖的是另一个版本的Guava库。图2.5展示了这种场景。
图2.5 Payment服务实现中的依赖传递
这种情况下,同一个库在Payment服务中会存在两个不同的版本。如果这两个库底层的大版本不一致,问题就会更加严重。这意味着它们甚至可能不是二进制兼容的。如果这两个库都存在于你的类路径中,你又没有做额外的配置,通常情况下你的构建工具(譬如Maven或者Gradle)会自动选择新版本的库。譬如可能出现这种情况,第三方库代码对27.0版本的Guava库中名为methodA的方法有依赖,而该方法在28.0版本的Guava库中被移除了。如果你没有在配置中明确指明使用哪个版本,构建工具就可能选择新版本的库。此时,就会发生类似MethodNotFound
这样的异常。这是因为第三方库期待使用27.0版本的Guava库中的methodA()
方法,而构建工具选择了28.0版本的Guava库,因此第三方库必须使用它。这就会导致上述问题的发生。这个问题很难解决,甚至可能让团队失去对你提取出来的库的信心。因此,你的库应该减少直接依赖。我们会在第9章和第12章更深入地讨论如何选择系统中的库。
在本节的场景里,我们假设新提取的库会同时被Payment和Person服务所使用。截至目前,没有固定的团队负责维护授权服务本身,因此两个团队都会参与到新的授权服务的开发工作中。这样一个库的开发工作需要在两个团队的成员间做一定的计划和协调。