面向接口编程的优点_为什么我们要面向接口编程

8b40790cf298fc9672e4f82897edbd10.png

到底面向?编程

面向过程编程( ProcedureOriented、简称 PO)面向对象编程( ObjectOriented、简称 OO) 我们一定听过,然而实际企业级开发里受用更多的一种编程思想那就是:面向接口编程( Interface-Oriented)

接口这个概念我们一定不陌生,实际生活中最常见的例子就是:插座!

我们只需要事先定义好插座的接口标准,各大插座厂商只要按这个接口标准生产,管你什么牌子、内部什么电路结构,这些均和用户无关,用户拿来就可以用;而且即使插座坏了,只要换一个符合接口标准的新插座,一切照样工作!

6506becd1f3b3846aea956cc9f7dff9a.png

同理,实际代码设计也是这样!

我们在设计一个软件的代码架构时,我们都希望事先约定好各个功能的接口(即:约定好接口签名和方法),实际开发时我们只需要实现这个接口就能完成具体的功能!后续即使项目变化、功能升级,程序员只需要按照接口约定重新实现一下,就可以达到系统升级和扩展的目的!

正好,Java中天生就有 interface这个语法,这简直是为面向接口编程而生的!

所以接下来落实到代码上,举个通俗一点的小例子唠一唠,实际业务代码虽然比这个复杂,但原理是一模一样的。


做梦了

假如哪一天程序羊真发达了,一口豪气买了两辆豪车,一辆五菱宏光、一辆飞度、并且还专门聘请了一位驾驶员来帮助驾驶。

两辆豪车在此:

a20766790c50e76635be1225585f50a2.png

驾驶员定义在此:

驾驶员定义了两个 drive()方法,分别用来驾驶两辆车:

39cb6cce9ce3d355ee9f22f2447936d2.png

这暂且看起来没问题!日子过得很融洽。

但后来过了段时间,程序羊又变得发达了一点,这次他又豪气地买了一辆新款奥拓(Alto)!

可是现有的驾驶员类 Driver的两个 drive()方法里都开不了这辆新买的奥拓该怎么办呢?


代码的灵活解耦

这时候,我想应该没有谁会专门再去往 Driver类中添加一个新的 drive()方法来达到目的吧?毕竟谁也不知道以后他还会不会买新车!

这时候如果我希望我聘请的这位驾驶员对于所有车型都能驾驭,该怎么办呢?

很容易想到,我们应该做一层抽象。毕竟不管是奥拓还是奥迪,它们都是汽车,因此我们定义一个父类叫做汽车类 Car,里面只声明一个通用的 drive()方法,具体怎么开先不用管:

e244f1d723eefe8a6df988669d017b9d.png

这时,只要我新买的奥拓符合 Car定义的驾驶标准即可被我的驾驶员驾驶,所以只需要新的奥拓来继承一下 Car类即可:

1763fd0903601c892ddc73f111e088b4.png

同理,只需要我的驾驶员具备通用汽车 Car的驾驶能力,那驾驶所有的汽车都不是问题,因此 Drvier类的 drive()方法只要传入的参数是父类,那就具备了通用性:

aa52cd3e41088777d3afa8f62633d1bb.png

问题暂且解决了!


但是再后来,程序羊他好像又更发达了一些,连车都不想坐了,想买一头驴(Donkey)让司机骑着带他出行!

很明显,原先适用于汽车的 drive()方法肯定是不适合骑驴的!但我们希望聘请的这位驾驶员既会开汽车,又会骑驴怎么办呢?

害!我们干脆直接定义一个叫做交通工具( TrafficTools)的通用接口吧!里面包含一个通用的交通工具使用方法,管你是驾驶汽车,还是骑驴骑马,具体技能怎么实现先不管:

a05061805a4c1482a6fff9438e1cfa85.png

有了这个接口约定,接下来就好办了。我们让所有的 Car、或者驴、马等,都来实现这个接口:

feef97b0a08e7cbefbb80c4ee78811e7.png

这个时候只要我们的驾驶员师傅也面向接口编程,就没有任何问题:

8060130c37307a715e5cc113791ad193.png

很明显,代码完全解耦了!这就是接口带来的便利。


代码的扩展性

面向接口编程的优点远不止上面这种代码解耦的场景,在实际企业开发里,利用接口思想对已有代码进行灵活扩展也特别常见。

再举一个例子:假设程序羊有一个非常豪气的朋友,叫:程序牛,他们家出行可不坐车,全靠私人飞机出行:

739585a043a034baaba1c3a4371cedee.png

但是突然有一天,他们家聘请的机长跳槽了,这时候程序牛一家就无法出行了,毕竟飞机不会驾驶。

于是他跑来问我借司机,想让我的驾驶员来帮他驾驶飞机出去旅行。

我一看,由于他们的代码面向的是接口,我就肯定地答应了他!

这时候对我这边的扩展来说就非常容易了,我只需要安排我的驾驶员去培训一下飞行技能就OK了(实现一个方法就行):

b5c50f1e3d274d70efad87d91b982535.png

这时候我的驾驶员 Driver类就可以直接服务于他们一家的出行了:

8584217d16abf22131beac3da8d4df0f.png

看到没,这一改造过程中,我们只增加了代码,却并没有修改任何已有代码,就完成了代码扩展的任务,非常符合开闭原则


实际项目

实际开发中,我们就暂且不说诸如 Spring这种框架内部会大量使用接口,并对外提供使用,就连我们自己平时写业务代码,我们也习惯于在 Service层使用接口来进行一层隔离:

d12bb59b57b03de4df5e255cf33e0856.png

这种接口定义和具体实现逻辑的分开,非常有利于后续扩展和维护!


小结

面向接口编程开发,对代码架构的解耦和扩展确实很有好处,这种编码思想也值得平时开发结合实践反复理解和回味!


每天进步一点点,Peace!

2020.03.04 晚

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/420341.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计模式:设计原则

程序设计的原则1. 单一设计原则2. 接口隔离原则3. 依赖倒转4. 里氏替换原则5. 开闭原则6. 迪米特原则7. 合成复用1. 单一设计原则 每一个类只负责做自己的的功能。不能跨越到其它类。 不合理 package top.bitqian.principle.single_responsibility;/*** author echo lovely* …

Android数据库LitePal的存储操作

本文属于转载,在此声明,出处:http://blog.csdn.net/guolin_blog/article/details/38556989 并且感谢guolin分享了这么精彩的博文。以下正文: 经过前面几篇文章的学习,我们已经把LitePal的表管理模块的功能都很好地掌握…

程控电源测试微安电流模式_无缝隙源和负载的切换:双向程控电源的一大门槛...

目前采用电池供电的直流无刷电机驱动的设备越来越多,从电动工具,无人机、机器人、再到电动汽车等。然而电机驱动器和电池的管理始终是研发工程师不得不面对的一道难题。电动机利用的是“电生磁”原理,把电能转换成机械能。但制动,…

前端学习(1324):anysc关键字

//只能出现再异步函数中 暂停异步函数得执行 async function fn() {throw 发生勒一些错误;return 123; } //console.log(fn()) fn().then(function(data) {console.log(data); }).catch(function(err) {console.log(err); }) 运行结果

Pacman主题下给Hexo增加简历类型

原文 http://blog.zanlabs.com/2015/01/02/add-resume-type-to-hexo-under-pacman-theme/ 背景 虽然暂时不找工作,但是想着简历也是个向别人推销自己的好东西。然后也想着折腾点新的东西,如此,这般,便想着研究起写个简历了。形式不…

屏幕输出语句_C语言快速入门——表达式与语句

表达式表达式是由运算符和操作数组合构造成。最简单的表达式是一个单独的操作数,以此作为基础,结合语言自身支持的操作符,就可以建立复杂的表达式。下面是一些表达式:从这里可以看到,操作数可以是数据常量(4&#xff0…

前端学习(1325):await关键字

async function p1() {return p1; } async function p2() {return p2; } async function p3() {return p3; } async function run() {let r1 await p1();let r2 await p2();let r3 await p3();console.log(r1);console.log(r2);console.log(r3);} run(); 运行结果

接口测试客户端的搭建

一. 引言 随着公司项目整体架构由原来的多渠道各自为战,向着建立统一的服务端应用,从而为各渠道提供服务调用的转变,服务端应用接口测试成了我们日常工作中的重要任务之一。经过半年的摸索和项目实战,我们已经掌握了一套接口测试的…

python对excel数据求和_96、python操作excel求和

这里介绍如何用python来自动完成我们的excel工作。本文的目的是展示一些常见的Excel任务,以及如何在python pandas中执行类似的任务。例子微不足道,但重要的是通过这个例子来循序渐进的介绍pandas简单到复杂的功能。展示pandas如何利用Python的完整的模块…

前端学习(1327):node全局对象global

global.console.log(我是歌谣); global.setTimeout(function() {console.log(123); }, 2000) 运行结果

4字节 经纬度_java 获取本机经纬度

package com.smm.web.mtower.util;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.net.URL;/*** Created by zhenghao on 2016/6/24.* 当前位置处理工具*/public class LocationUtil {/*…

C#秘密武器之反射——基础篇

先来一段有用的反射代码 namespace Calculator { public interface Iwel { String Print(); } } namespace Calculator { public class Arithmetic:Iwel { /// <summary> /// 没有带参数的构造函数 /// </summary> public Arithmetic() {} public Arithmetic(i…

python社区版可以用库么_应用Python,你不但能够得到出色的小区适用和普遍的库集...

哪样计算机语言最好是&#xff1f;这个问题很有可能始终不容易找答案。萝卜青菜&#xff0c;各有所好&#xff0c;AI技术工程师和生物学家能够依据新项目必须&#xff0c;从诸多计算机语言中挑选最合适自身的。选Python還是选Java?2020年&#xff0c;顶级程序猿最应当把握的7种…

Python3 etree, requests库抓取bt

bt种子抓取1. 抓取你想要的数据2. 爬取bt种子3. 抓取磁力链迷上了追番.. . bt种子xunlei来解决。 推荐一个网站https://mikanani.me。可以搜索你想要的动漫… 以bt的形式下载&#xff0c;或者复制磁力链。 1. 抓取你想要的数据 需要了解requests, etree库&#xff0c;etree用…

ecshop各个文件夹作用

Images文件夹&#xff1a;这个文件夹下有子文件夹&#xff0c;在这些子文件夹下面存放着当前网站商品的原始图片和缩略图。这些子文件夹命名有规律的&#xff0c;它们的文件名是它们目录下商品加入 的年月份。也就是说在同一个月份加入的商品&#xff0c;它们的图片是在同一个文…

unity2018关联不到vs_现实VS真爱:远嫁的幸福和悲哀

陆拾一 LUSHIYI《现实VS真爱&#xff1a;远嫁的幸福和悲哀》Part.1你有过远嫁的犹豫或者经历吗&#xff1f;关于这个话题&#xff0c;我从未写过。今天借着一封读者的来信&#xff0c;与大家聊一聊。拾一&#xff0c;你好。我跟男朋友在一起两年了&#xff0c;现在到了谈婚论嫁…

dubbo使用nacos作为注册中心

spring-cloud nacos dubbodubbo接口服务提供者消费者&#xff0c;要订阅对应的服务&#xff0c;订阅提供者使用openFeign以http为协议进行rest调用。而dubbo是tcpport&#xff0c;使用tcp协议的。 版本说明 dubbo : 2.7.8 spring-cloud-alibaba: 2.1.4.RELEASE spring-cloud:…