09 | 理论六:为什么基于接口而非实现编程?有必要为每个类都定义接口吗?
王争
该思维导图由 AI 生成,仅供参考
在上一节课中,我们讲了接口和抽象类,以及各种编程语言是如何支持、实现这两个语法概念的。今天,我们继续讲一个跟“接口”相关的知识点:基于接口而非实现编程。这个原则非常重要,是一种非常有效的提高代码质量的手段,在平时的开发中特别经常被用到。
为了让你理解透彻,并真正掌握这条原则如何应用,今天,我会结合一个有关图片存储的实战案例来讲解。除此之外,这条原则还很容易被过度应用,比如为每一个实现类都定义对应的接口。针对这类问题,在今天的讲解中,我也会告诉你如何来做权衡,怎样恰到好处地应用这条原则。
话不多说,让我们正式开始今天的学习吧!
如何解读原则中的“接口”二字?
“基于接口而非实现编程”这条原则的英文描述是:“Program to an interface, not an implementation”。我们理解这条原则的时候,千万不要一开始就与具体的编程语言挂钩,局限在编程语言的“接口”语法中(比如 Java 中的 interface 接口语法)。这条原则最早出现于 1994 年 GoF 的《设计模式》这本书,它先于很多编程语言而诞生(比如 Java 语言),是一条比较抽象、泛化的设计思想。
实际上,理解这条原则的关键,就是理解其中的“接口”两个字。还记得我们上一节课讲的“接口”的定义吗?从本质上来看,“接口”就是一组“协议”或者“约定”,是功能提供者提供给使用者的一个“功能列表”。“接口”在不同的应用场景下会有不同的解读,比如服务端与客户端之间的“接口”,类库提供的“接口”,甚至是一组通信的协议都可以叫作“接口”。刚刚对“接口”的理解,都比较偏上层、偏抽象,与实际的写代码离得有点远。如果落实到具体的编码,“基于接口而非实现编程”这条原则中的“接口”,可以理解为编程语言中的接口或者抽象类。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
本文深入探讨了“基于接口而非实现编程”的重要性以及如何在实际编码中应用这一原则。作者首先解释了“基于接口而非实现编程”原则的含义,强调了将接口和实现相分离,封装不稳定的实现,暴露稳定的接口的重要性。文章指出,这一原则可以降低代码的耦合性,提高代码的扩展性,使代码更加灵活应对未来的需求变化。通过具体的实战案例,文章展示了如何在代码中应用这一原则,以及如何通过重构代码来遵循“基于接口而非实现编程”的原则。作者还提到了“基于抽象而非实现编程”是这一原则的另一种表述方式,强调了抽象是提高代码扩展性、灵活性、可维护性最有效的手段之一。总的来说,本文通过解释原则的含义、重要性以及如何在实际编码中应用,帮助读者更好地理解了“基于接口而非实现编程”的概念。文章还强调了在设计接口时要遵循抽象意识、封装意识、接口意识,不暴露任何实现细节,以及在业务场景中根据实现的稳定性来决定是否需要定义接口。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《设计模式之美》,新⼈⾸单¥98
《设计模式之美》,新⼈⾸单¥98
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(306)
- 最新
- 精选
- 👽那现在的MVC代码,要求service先写接口,然后再写实现,有必要嘛? 说实话,我一直没看懂这种行为的意义何在。
作者回复: 确实意义不大
2019-11-251914 - bearlu老师,希望能把示例代码和问题代码也放到Github上。
作者回复: 👌 我抽空整理一下放上去 https://github.com/wangzheng0822
2019-11-2225 - 大智思考题的话,结合spring的话我觉得应该是初始化一个存储处理类并在使用类中@Autowired即可。初始化哪个类取决于你给哪个存储类进行了初始化
作者回复: 嗯嗯
2020-11-2324 - tuyu老师, 我今天碰到一个问题, 如果我创建阿里云k8s, 那么参数是很多很多, 根据接口原则, 我不太清楚未来不同云平台创建k8s需要哪些参数, 那我应该怎么做
作者回复: 这个就没法抽象成接口了,只能每个不同的云平台不同处理了。我们也没法追求在替换云平台时,一点代码都不改。尽量少改动代码就可以了。
2020-05-094 - Geek_5a5d9a我的想法是对外提供构造函数, 构造不同场景的上传, 例如: public ImageProcessingJob aliyunProcessingJob() { // 设置类的基本属性 // self.imageStore = new AliyunImageStore() } public ImageProcessingJob privateProcessingJob() { // 设置类的属性 // self.imageStore = new PrivateImageStore() }
作者回复: ������
2020-11-172 - Geek_East想问个问题,泛型的主要目的是代码复用还是抽象呀?
作者回复: 代码复用
2020-05-212 - 刘小辉第一:思考题我觉得可以用SPI! 第二: 抽象类的功能应该远远多于接口。但是定义抽象类的代价是比较高的。因为像java,C#这样的高级语言,是不允许多继承的所以,你在设计一个父类为抽象类的时候,一定得将这个类的子类所有的共同属性和方法都定义出来;但是接口可以不用这样。因为接口是一个方法的集合,一个类可以实现多个接口。所以,你的接口里面只有一个方法,还是两个方法,都是可以的。之后如果还有新的方法,我大不了再设计一个接口就是了。所以说,抽象类的设计必须谨慎,接口的设计很灵活。
作者回复: ������
2020-11-271 - 李二木我们在做软件开发的时候,一定要有抽象意识、封装意识、接口意识。越抽象、越顶层、越脱离具体某一实现的设计,越能提高代码的灵活性、扩展性、可维护性。
作者回复: 说的没错
2020-11-24 - 刘永超老师把行业“黑话”讲透彻了,捅破那层窗户纸,不用再纠结于一些基本概念。
作者回复: 哈哈,爱你
2020-11-14 - varoteneProgramming against interface 是不是也是抽象(abstraction)的一种手段?把原来具体的问题或者实现(aliyun或者私有云)抽象成任意的云,然后通过interface来予以描述。 至于什么时候用interface,什么时候不用,感觉也跟什么时候用抽象什么时候不用抽象是一个道理?因为进行抽象是需要成本的, 但不需要的时候,我们就可以略过,节省工程成本(YAGNI原则)。这么理解对吗?
作者回复: 理解的没问题~ 基于接口而非实现是一种抽象的思维
2020-01-06
收起评论