如何设计一个好的接口

作者: 欧阳锋 | 来源:发表于2016-03-29 13:41 被阅读4039次

前言

代码每个人都会写。但是,能把代码写的优美,把结构设计的足够灵活,并且让人赞叹的人却很少。尤其在中国这样的大环境里。大部分人都是为了生活而奔波。编程只不过是一份工作而已。所以,我想,你肯定也曾经像我一样,看到很多想骂娘的代码。这些代码通常被称之为面条代码,所谓的面条代码,就是写的像长妈妈的裹脚布一样,又臭又长。让人理不清,理还乱,是离愁,别是一番滋味在心头。

笔者工作只不过短短几年,但从来不敢轻视编程,一直视编程为一件非常神圣的事情。从一开始,我就严格按照代码格式去构建我的代码,最初的时候,拿开发工具格式化基本都没有变化。现在想想,正是源于当初对待编程战战兢兢,如履薄冰一般,才有了现在非常漂亮的代码习惯。在笔者工作的这几年里,每天和Code约会的时间最长,先后掌握了Java,C++,OC,Swift等语言,工作中接触最多的还是Java语言,但从其他语言中我也吸收了很多营养。鉴于笔者这些年的经验,希望写一篇文章讲一讲接口的设计,笔者水平有限,文章只当是抛砖引玉,如果有更好的设计,请在文章下方留言告诉我。

避免过度封装

这是我想说的第一点,很多人喜欢这样封装,把接口局限在仅仅解决一个特定的问题上面,失去了代码的灵活性。而且,也容易出现面条代码,让人不知所云。笔者的工作中已经遇到了很多这样的问题,一个接口被写的仅仅用于解决当前问题,当笔者试图增加其扩展性时,发现为时已晚。任我移花接木,甚至是斗转星移都无法使其逆转。遇到这种情况,笔者常常是另辟蹊径,将垃圾接口代码标注为@Deprecated,重新写一套接口。为了防止过度封装,在设计接口的时候,我们应该考虑以下几个问题:

  • 我们需要解决什么问题
  • 问题的核心是什么
  • 应该怎样设计,可以方便客户程序员扩展

第一点,我们需要找出我们将要解决的问题,这个看似容易的工作,其实并不容易,很多人即便遇到了问题,依然不知道自己到底要解决什么问题。只是使用一些面条代码,饮鸩止渴。最终,害人害己。

第二点,我们需要找出问题的核心,一定要记住,是找出问题的核心,而不是直接解决问题的方法。如果你只是找出直接解决问题的方法。那么,这个代码一定是不具有任何扩展性,也不能称之为接口。我们只能认为,他写了一堆代码,解决了一个问题。

第三点,一定要充分考虑接口的可扩展性,这就要求在做接口设计的时候,要站在客户程序员的角度去想问题。他要怎样使用我的代码,他会如何扩展我的代码。所以,记得要该放手时就放手,不要把过多的工作写在你的接口里面,而应该把更多的主动权交给客户程序员。

见名知意

接口中,方法的设计一定要力求简洁,而且要见名知意。如果笔者的同事有在注意笔者编码的话,一定会发现,笔者在设计接口的时候,花在名称的定义上时间是很长的。
这里举一个简单的例子,在Java语言中,单例的方法名几乎已经是习惯了,叫做getInstance()。可是,仔细想一想,getInstance()真的可以表达单例的意思吗?答案是:完全不能。getInstance()更像是工厂方法的命名。而笔者认为OC语言命名单例的方法就高明了许多,iOS程序员一定熟悉sharedInstance()方法,共享的单例。一下子就将单例的意思表达的简明扼要,如流水般清晰自然。

这只是一个简单的例子,笔者希望告诉大家,在设计的接口的时候,接口的名称一定不能偷懒,拿发起POST请求的方法名命名。如果你称之为sendReq()。那么,请问客户程序员怎么知道这是要发起GET请求还是POST请求?客户程序员在使用这个方法的时候无疑要点击进入源码查看,大大增加了开发成本。
因此,笔者认为,一个好的的接口方法名,是接口设计中成功的一半。而要想让接口设计的优雅,自然,请继续关注下面的文章。

仅把必要的工作交给客户程序员

什么叫必要,这里可以理解为,当前无法估计的操作。比如转换到具体的数据类型,而具体是什么类型,接口设计者是未知的。那么这个操作就可以交给客户程序员。同时,要注意的是,不要给客户程序员过多的工作。过多的工作设计就意味着这个接口的设计是完全失败的。同时,也不符合接口的概念。充其量也只能称之为解决一个问题。所以,设计的时候要记得尽可能简化客户程序员逻辑,使接口设计能够看起来简洁、漂亮,而不至于被接口的复杂性所吓倒。

充分保证程序的可扩展性

其实做到上面几点,程序的可扩展性基本已经有了保证,但还有一些工作必不可少。在设计接口的时候,要充分考虑是否需要被重写,如果需要被重写,考虑标注protected。否则,标注private。对于不明确的方法,请慎重考虑,被重写的可能性。如果几乎为0,则不考虑其被重写。另外,在保证充分可扩展性的前提下,也要保证数据的完整性,不可因为客户程序的错误访问,导致接口设计出现异常。所以,适度很重要,不要因为扩展性而丢失了数据的完整性。

简洁

接口的设计一定要充分简洁。这很重要,见过很多程序员,为了保证接口的充分可用性,设计了一堆参数。但其实,大部分情况下客户程序员只需要一两个参数即可。这样的设计就违背了接口设计的简洁原则。会让很多客户程序员望而生畏,放弃对该接口的使用。或者进行二次封装。所以,简洁设计是接口设计的一个重要原则。可以在接口的内部实现中,使用复杂冗余的参数,而在暴露给客户程序员的接口中,一定要尽可能简洁。

百分比原则

在接口的设计中,难免要设置一些默认操作,在设计默认操作的时候,一定要充分考虑用户的使用习惯。比如接口的操作有两种,要充分对比这两种操作频繁度。这里假设操作有A,B两种,如果A操作更为频繁,则应该将A操作设为默认,反之,则为B。这里可以认为A操作的百分比超过了50%,故取其作为默认值,笔者将其称为百分比原则。即根据操作的频繁度依次排名,取百分比最大的操作为默认值。

文档表述要清晰

良好的接口设计,离不开清晰的接口文档表述。文档表述一定要足够详细,使客户程序员充分知道该接口的用法以及需要注意的问题。这一点是很多接口设计者容易忽略的。但这一点的重要性,笔者认为甚至超越了上面所有点的总和。

总结

接口的设计是实际开发中必不可少的一环,也是最重要的一环。良好的接口设计能够起到事半功倍的效果,而杂乱无章的接口设计有时甚至会造成无法挽回的损失。因此,在设计接口的时候,请慎重考虑上面的设计原则。有一句古话告诉我们,磨刀不误砍柴工,说的就是这个道理!

相关文章

  • 如何设计一个好的接口

    前言 代码每个人都会写。但是,能把代码写的优美,把结构设计的足够灵活,并且让人赞叹的人却很少。尤其在中国这样的大环...

  • 使用 Protobuf 设计 REST API

    概述 一个设计的好的 REST API 接口,需要一个严格的接口定义。本文试图使用 Protobuf 作为接口设计...

  • 软件设计模式-接口隔离

    这个原则是 明确了 如何设计对接口!怎么用接口。 从前面开始我们就知道了接口的好处,如何设计好的接口呢?那么接口隔...

  • 设计一个好的接口

    一个程序员问禅师?”什么是好的接口“, 接口的功用和翻译类似(人和系统的界面层,沟通的媒界),信,达,雅也许是一个...

  • Android开发最佳实践——1.接口设计

    Android开发最佳实践——1.接口设计 一个项目刚开始的时候,最需要确认的就是接口设计了:数据如何传递,使用什...

  • 接口测试断言从哪些方面去设计?

    你去如何做断言的?从哪些方面去设计断言? 去做接口测试,我们要把这个接口测试好,从哪些方面去考虑? 其实Postm...

  • 如何设计接口

    接口是用来系统间通信的定义,尤其异构系统之间的通信,接口的设计尤其重要。 一、 什么是好的接口? 对接口调用方来说...

  • 哪种人是软件设计中的稀缺型人才?

    阿里妹导读:好的系统架构离不开好的接口设计,因此,真正懂接口设计的人往往是软件设计队伍中的稀缺型人才。为什么在接口...

  • java程序员笔记--Dubbo服务接口的设计原则

    1.设计方式 action->facade->biz->dao 好的Dubbo服务接口设计,并非只是纯粹的接口服务...

  • web-api总结

    总结一下ruby中如何写设计api接口: 1.api是程序之间的接口,一个服务端api接口包含http方法,URL...

网友评论

  • 李戬plutocracy:接口的不是为扩展而生
  • 叕之燚:这种东西,真的只有做久了,写多了,看多了,才能理解里面真正的含义,才能慢慢写出自己开始满意的代码,然后一步一步优化
    欧阳锋:@iCocos 在理
  • 6e21db636049:我没觉得那么神圣,倒是感觉是在磨小刀。不停地修改变量名称,没完没了的。工匠精神
  • wuyangLi:作者你好 可以提供下你的开源项目吗 github上的 我做ios开发的 最近接受SDK 想看看优美的代码 然后和你探讨下
  • 呼吸的蜗牛:哥哥啊!我觉得,这种实际型的东西,你最好有一个代码示范,对比才能产生美。
    欧阳锋:@呼吸的蜗牛 😁 最好是自己悟哈

本文标题:如何设计一个好的接口

本文链接:https://www.haomeiwen.com/subject/vnljlttx.html