深度思考:到底什么是面向接口编程?

简介: 深度思考:到底什么是面向接口编程?

在以往的编程学习中,我们听说过很多编程概念,比如面向对象编程(OOP)、面向方面编程(AOP)、面向过程编程(POP),以及还有今天要进行深入思考的面向接口编程(IOP)。计算机的发展已经足足七十多年,编程语言的发展也有了六七十年的历史,而近二三十年随着互联网和高级编程语言的不断崛起,整个程序设计行业发展的越来越快,沉淀的也越来越多,因而诞生了诸如以上的很多不同的编程思想。

首先,第一个问题。

1 什么是接口?

接口一词听起来更像是一个物理学电学上的东西,比如USB接口、Type-C接口等等,当然在计算机科学中也十分的常见,主要分为硬件和软件两个层面:

  • 硬件层的接口:两个硬件设备之间的连接方式和媒介
  • 软件层的接口:软件设计和应用服务不同功能层之间的通信规则

当然,在编程语言中接口还可以再细化,比如在Java语言中,接口是一个抽象的类,而在Go语言中,接口则是一种类型。

接下来,第二个问题。

2 什么是面向接口编程?

什么是面向接口编程?为什么要面向接口编程?

简单的讲,面向接口编程是一种编程规范,一种设计规范,可以更好的进行需求的定义和业务的扩展,我们可以从以下三个方面来探讨为什么要面向接口编程:

  • 开闭原则:对扩展开放,对修改关闭,接口正是如此,定义接口后不再修改,只扩展其对应的实现。
  • 依赖倒置原则:高层模块不应该依赖于低层模块,他们应该共同依赖于抽象,而这个抽象就是接口。
  • 增加抽象层、解耦:接口显然是对抽象的一个封装,能够达到解耦的目的。

2.1 业务需求分析

假设我们有一个产品经理想要与开发工程师对接需求,有的需求在数据库层面,属于数据需求,有的在业务层面,属于功能需求,这样就导致了在产品经理和工程师沟通时存在一些复杂的程度,比如产品经理要先了解每个工程师都对应的哪方面的业务需求,再与其进行需求的对接等等。

网络异常,图片无法展示
|


上述情况,如果是工程师数量少的话影响并不大,但是当工程师多了以后问题就会非常繁琐,因此我们需要定义一个规范,由工程师统一的回答,可以理解成为问题的提问与解释的模板,当换了工程师或换了业务之后,接口并没有换,实现依然可以扩展,这就是面向接口编程的魅力!

对于以上的需求分析,我们作出一个代码实例,因为Java、Go都是可以面向接口编程,因此我们对两个语言的面向接口编程都作出简单的示例:

  • 定义接口为工程师抽象,分别有coding和play抽象方法
  • 针对该抽象作出两个实现,分别是DB工程师和Sys(系统)工程师
  • main函数和test可以想象为产品经理对接口的实现进行查验

2.2 Java面向接口编程实现

@Test
void test() {
    Programmer programmer = new DBProgrammer("zs");
    programmer.coding("SQL");
}
//接口 -> 规范
interface Programmer {
    void coding(String code);
    void play(String ball);
}
//DB程序员
class DBProgrammer implements Programmer {
    private String name;
    public DBProgrammer(String name) {
        this.name = name;
    }
    @Override
    public void coding(String code) {
        System.out.println("I am DB Programmer " + this.name + " and coding " + code + ".");
    }
    @Override
    public void play(String ball) {
        System.out.println("I am DB Programmer " + this.name + " and playing " + ball + ".");
    }
}
//系统程序员
class SysProgrammer implements Programmer {
    private String name;
    public SysProgrammer(String name) {
        this.name = name;
    }
    @Override
    public void coding(String code) {
        System.out.println("I am Sys Programmer " + this.name + " and coding " + code + ".");
    }
    @Override
    public void play(String ball) {
        System.out.println("I am Sys Programmer " + this.name + " and playing " + ball + ".");
    }
}
复制代码

2.3 Go面向接口编程实现

接口

type Programmer interface {
   Coding(code string)
   Play(ball string)
}
复制代码

ProgrammerDB实现

type ProgrammerDB struct {
   Name   string
   Age    int
   DBName string
}
func (db ProgrammerDB) Coding(code string) {
   fmt.Println("I am DB Programmer", db.Name, "and I am coding", code, ".")
}
func (db ProgrammerDB) Play(ball string) {
   fmt.Println("I am DB Programmer", db.Name, "and I am playing", ball, ".")
}
复制代码

ProgrammerSys实现

type ProgrammerSys struct {
   Name    string
   Age     int
   SysName string
}
func (sys ProgrammerSys) Coding(code string) {
   fmt.Println("I am Sys Programmer", sys.Name, "and I am coding", code, ".")
}
func (sys ProgrammerSys) Play(ball string) {
   fmt.Println("I am Sys Programmer ", sys.Name, " and I am playing ", ball, ".")
}
复制代码

测试

func main() {
   sys := ProgrammerSys{Name: "zs"}
   sys.Coding("Java")
   db := ProgrammerDB{Name: "ls"}
   db.Coding("SQL")
}
复制代码

3 思考

到这里,讲了这么多,其实最终的总结很简单:接口的本质就是抽象和规范,接口是抽象的产物,应用于规范

网络异常,图片无法展示
|


使用接口可以更好的将我们的系统进行解耦,不管是多系统之间(如RPC框架),还是同一系统多模块之间,接口所扮演的抽象的角色都是不可替代的。

今天的分享就到这里,如有哪里理解的不够深入,请读者朋友不吝赐教哈~


相关文章
|
程序员 开发工具 Android开发
Android|使用阿里云推流 SDK 实现双路推流不同画面
本文记录了一种使用没有原生支持多路推流的阿里云推流 Android SDK,实现同时推送两路不同画面的流的方法。
288 7
|
人工智能 自然语言处理 物联网
llama factory 从数据集起步 跑通 qwen系列开源生成式大模型 微调
`dataset_info.json` 文件用于管理 llama factory 中的所有数据集,支持 `alpaca` 和 `sharegpt` 格式。通过配置此文件,可以轻松添加自定义数据集。数据集的相关参数包括数据源地址、数据集格式、样本数量等,支持 Hugging Face 和 ModelScope 两个平台的数据集仓库。针对不同格式的数据集,提供了详细的配置示例,如 `alpaca` 格式的指令监督微调数据集、偏好数据集等,以及 `sharegpt` 格式的多模态数据集等。今天我们通过自定义数据集的方式来进行qwen2.5_14B_instruct模型进行微调
6572 7
|
消息中间件 存储 监控
解决方案 | 云消息队列RabbitMQ实践
在实际业务中,网站因消息堆积和高流量脉冲导致系统故障。为解决这些问题,云消息队列 RabbitMQ 版提供高性能的消息处理和海量消息堆积能力,确保系统在流量高峰时仍能稳定运行。迁移前需进行技术能力和成本效益评估,包括功能、性能、限制值及费用等方面。迁移步骤包括元数据迁移、创建用户、网络打通和数据迁移。
373 4
给kprobe添加字符数据显示方式
给kprobe添加字符数据显示方式
|
人工智能 安全 Linux
人工智能时代下,国产服务器操作系统如何加快发展?
【4月更文挑战第3天】人工智能时代下,国产服务器操作系统如何加快发展?
|
存储 固态存储 Unix
Linux中磁盘分区和文件系统管理
在Linux系统中,磁盘是存储数据的物理设备,如HDD或SSD,以文件形式存在于`/dev`目录下,如`sda`、`sdb`等。文件系统定义了如何在磁盘上组织和访问数据,常见的Linux文件系统有ext2、ext3、ext4、xfs等。通过虚拟机软件如VMware,用户可以向Linux虚拟机添加新的硬盘。
264 1
|
存储 C语言 C++
实战C++:如何开发一个完整的学生信息管理系统?
先简单介绍一下这篇文章,这是一篇关于C++的学生管理系统的文章,作为从C语言到C++过渡的项目。
499 0
|
SQL 监控 测试技术
PTS压测问题之token值不一样配置如何解决
PTS(Performance Testing Service)是一项面向网站、应用等提供的压力测试服务,用于模拟不同场景下的用户访问,评估系统的性能表现;在进行PTS压测时,可能会出现一些异常或报错,本合集将PTS压测中频繁出现的问题及其解决办法进行汇编,旨在帮助用户更有效地进行性能测试和问题定位。
493 1
|
JavaScript API
onbeforeunload事件之关闭浏览器之前的提示弹框
onbeforeunload事件之关闭浏览器之前的提示弹框
877 0
|
存储
【二叉树】——链式结构(快速掌握递归与刷题技巧)
【二叉树】——链式结构(快速掌握递归与刷题技巧)
317 0