现在的位置:主页 > 综合新闻 >

为什么基于接口而非实现编程?有必要为每个类

来源:电脑编程技巧与维护 【在线投稿】 栏目:综合新闻 时间:2020-08-26

【作者】网站采编

【关键词】

【摘要】我们知道基于接口而非实现编程。这个原则非常重要,是一种非常有效的提高代码质量的手段,在平时的开发中特别经常被用到。 今天结合一个有关图片存储的实战案例来讲解。除此之

我们知道基于接口而非实现编程。这个原则非常重要,是一种非常有效的提高代码质量的手段,在平时的开发中特别经常被用到。

今天结合一个有关图片存储的实战案例来讲解。除此之外,这条原则还很容易被过度应用,比如为每一个实现类都定义对应的接口。针对这类问题,在今天的讲解中,我也会告诉你如何来做权衡,怎样恰到好处地应用这条原则。

如何解读原则中的“接口”二字?

“基于接口而非实现编程”这条原则的英文描述是:“Program to an interface, not an implementation”。我们理解这条原则的时候,千万不要一开始就与具体的编程语言挂钩,局限在编程语言的“接口”语法中(比如 Java 中的 interface 接口语法)。这条原则最早出现于 1994 年 GoF 的《设计模式》这本书,它先于很多编程语言而诞生(比如 Java语言),是一条比较抽象、泛化的设计思想。

实际上,理解这条原则的关键,就是理解其中的“接口”两个字。还记得我们上一节课讲的“接口”的定义吗?从本质上来看,“接口”就是一组“协议”或者“约定”,是功能提供者提供给使用者的一个“功能列表”。“接口”在不同的应用场景下会有不同的解读,比如服务端与客户端之间的“接口”,类库提供的“接口”,甚至是一组通信的协议都可以叫作“接口”。刚刚对“接口”的理解,都比较偏上层、偏抽象,与实际的写代码离得有点远。如果落实到具体的编码,“基于接口而非实现编程”这条原则中的“接口”,可以理解为编程语言中的接口或者抽象类。

前面我们提到,这条原则能非常有效地提高代码质量,之所以这么说,那是因为,应用这条原则,可以将接口和实现相分离,封装不稳定的实现,暴露稳定的接口。上游系统面向接口而非实现编程,不依赖不稳定的实现细节,这样当实现发生变化的时候,上游系统的代码基本上不需要做改动,以此来降低耦合性,提高扩展性。实际上,“基于接口而非实现编程”这条原则的另一个表述方式,是“基于抽象而非实现编程”。后者的表述方式其实更能体现这条原则的设计初衷。在软件开发中,最大的挑战之一就是需求的不断变化,这也是考验代码设计好坏的一个标准。越抽象、越顶层、越脱离具体某一实现的设计,越能提高代码的灵活性,越能应对未来的需求变化。好的代码设计,不仅能应对当下的需求,而且在将来需求发生变化的时候,仍然能够在不破坏原有代码设计的情况下灵活应对。而抽象就是提高代码扩展性、灵活性、可维护性最有效的手段之一。

如何将这条原则应用到实战中?

对于这条原则,我们结合一个具体的实战案例来进一步讲解一下。假设我们的系统中有很多涉及图片处理和存储的业务逻辑。图片经过处理之后被上传到阿里云上。为了代码复用,我们封装了图片存储相关的代码逻辑,提供了一个统一的AliyunImageStore 类,供整个系统来使用。具体的代码实现如下所示:

//... 省略属性、构造函数等...public void createBucketIfNotExisting(String bucketName) {// ... 创建 bucket 代码逻辑...// ... 失败会抛出异常..}public String generateAccessToken() {// ... 根据 accesskey/secrectkey 等生成 access token}public String uploadToAliyun(Image image, String bucketName, String accessTok//... 上传图片到阿里云...//... 返回图片存储在阿里云上的地址 (url)...}public Image downloadFromAliyun(String url, String accessToken) {//... 从阿里云下载图片...}}// AliyunImageStore 类的使用举例public class ImageProcessingJob {private static final String BUCKET_NAME = \"ai_images_bucket\"//... 省略其他无关代码...public void process() {Image image = ... // 处理图片,并封装为 Image 对象AliyunImageStore imageStore = new AliyunImageStore(/* 省略参数 */)(BUCKET_NAME)String accessToken = ()(image, BUCKET_NAME, accessToken)}}

整个上传流程包含三个步骤:创建 bucket(你可以简单理解为存储目录)、生成 accesstoken 访问凭证、携带 access token 上传图片到指定的 bucket 中。代码实现非常简单,类中的几个方法定义得都很干净,用起来也很清晰,乍看起来没有太大问题,完全能满足我们将图片存储在阿里云的业务需求。不过,软件开发中唯一不变的就是变化。过了一段时间后,我们自建了私有云,不再将图片存储到阿里云了,而是将图片存储到自建私有云上。为了满足这样一个需求的变化,我们该如何修改代码呢?

文章来源:《电脑编程技巧与维护》 网址: http://www.dnbcjqywh.cn/zonghexinwen/2020/0826/422.html

上一篇:C/C++编程笔记:C语言编程需要掌握的核心要点有
下一篇:C/C++编程笔记:计算机网络基础知识总结!超全面

电脑编程技巧与维护投稿 | 电脑编程技巧与维护编辑部| 电脑编程技巧与维护版面费 | 电脑编程技巧与维护论文发表 | 电脑编程技巧与维护最新目录
Copyright © 2018 《电脑编程技巧与维护》杂志社 版权所有
投稿电话: 投稿邮箱: