什么时候该用接口?
阿里高级技术专家张建飞
讲述:丁婵大小:7.36M时长:05:21
在上一篇文章中,我们分享了阿里巴巴国际化事业部高级技术专家张建飞对于接口在软件设计中的两大好处的分析,即制定标准和提供抽象。那么,什么时候要用接口?如何实现面向接口呢?以下是张建飞对这些问题的解答。
什么时候要用接口?
1. 有扩展性需求的时候
可扩展设计,主要是利用了面向对象的多态特性,所以这里的接口是一个广义的概念,如果用编程语言的术语来说,它既可以是 Interface,也可能是 Abstract Class。
这种扩展性的诉求在软件工作中可以说无处不在,甚至小到一个工具类。例如,我现在系统中需要一个开关的功能,开关的配置目前是数据库,但后续可能会迁移到 Diamond 配置中心,或者 SwitchCenter 上。
简单做法就是,我直接用数据库的配置去实现开关功能,
但这样做的问题很明显,当需要切换新的配置实现时,就不得不扒开原来的应用代码做修改。更恰当的做法应该是提供一个 Switch 的接口,让不同的实现去实现这个接口,从而在切换配置实现时,应用代码不必再做更改。
如果说,上面的重构只是使用策略模式对代码进行了局部优化,做了当然更好,不做的话,也可以将就着过。
那么接下来这个场景,就不仅仅是“要不要”的问题,而是“不得不”的问题了。
例如,老板给你布置了一个任务,实现一个类似于 eclipse 可插拔(Pluggable)的产品,此时,使用接口就不仅仅是一个选择问题了,而是你不得不使用的架构方法。因为,可插拔的本质就是,你制定一个标准接口(API),然后由不同的实现者去做插件的实现,最后再由插件管理器将这个插件机制串起来。
2. 需要解耦的时候
上面介绍的关于 Switch 的例子,从表面上来看,是扩展性的诉求。但不可扩展的根本原因正是耦合性。当我们通过 Switch Interface 来解开耦合之后,扩展性的诉求也就迎刃而解了。
发现这种耦合性,对系统的可维护性至关重要。有一些耦合比较明显,但更多的耦合是隐性的。在很长一段时间内,它不会造成什么问题,但是,一旦问题形成,就会非常令人头痛。因此,及时预见问题的存在,用接口做解耦将会为你省去不少麻烦。
3. 要给外界提供 API 的时候
无论是成功的 JSR,还是失败的 JSR,其本质都是在定义标准、制定接口。其规范的内容都是抽象的,其对外发布的形式都是接口,它不提供实现,最多会指导实现。
还有我们通常使用的各种开放平台的 SDK,或者分布式服务中 RPC 的二方库,其包含的主要成分也是接口,其实现不在本地,而是在远程服务提供方。
类似于这种 API 的情况,都是在倒逼开发者要把接口想清楚。我想,这也算微服务架构一个漂亮的“副作用”吧。当原来单体应用中各种耦合的业务模块被服务化之后,就自然而然的变成“面向接口”了。
通过依赖倒置实现面向接口
依赖倒置原则主要规定了两件事情:
高层模块不应该依赖底层模块,两者都应该依赖抽象;
抽象不应该依赖细节,细节应该依赖抽象。
依赖倒置原则不仅在对象设计、模块设计时有用。在架构设计的时候也非常有用。比如,我在做 COLA 1.0 时,和大多数应用架构分层设计一样,默许了 Domain 层可以依赖 Infrastructure 层。这其中存在了不小的隐患,也违背了我当初想把业务复杂度和技术复杂度分开的初心。当业务变得更加复杂时,这种“偷懒”行为很可能会导致 Domain 层堕落成大泥球(Big mud ball)。因此,在 COLA 2.0 的时候,我决定用依赖倒置原则反转 Domain 层和 Infrastructure 层的关系。
这样做的好处是 Domain 层会变得更加纯粹,主要体现在以下三点:
解耦: Domain 层完全摆脱了对技术细节的依赖,只需要安心处理业务逻辑就好了。
并行开发: 在 Domain 和 Infrastructure 约定好接口,两个同学并行编写二者的代码。
可测试性: 没有任何依赖的 Domain 里面都是 POJO 的类,单元测试将会变得非常方便,也非常适合 TDD 的开发。
当然,和许多其它软件原则一样,面向接口很好,但如果不分背景或过度使用接口,过多引入间接层也会带来一些不必要的复杂度。
以上就是今天的内容,希望对你有所帮助。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
该免费文章来自《极客视点》,如需阅读全部文章,
请先领取课程
请先领取课程
免费领取
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
精选留言
由作者筛选后的优质留言将会公开显示,欢迎踊跃留言。
收起评论