没有被相识的API?一个老码农眼中的API世界

作者:澳门皇冠棋牌娱乐平台发布时间:2022-10-24 00:30

本文摘要:没有被相识的API?一个老码农眼中的API世界 即便做了20多年的软件开辟,仍然发明本身常常会低估完成一个特定的编程任务所需要的时间。有时,错误的时间表是由于本身的能力不足造成的: 当深入研究一个问题时,会发明它比最初想象的要可贵多,因此解决这个问题需要更长的时间ーー这就是法式员的糊口。纵然本身清楚地知道想要实现什么以及如何实现它,还会常常比预期的要花费更多的时间,这种环境往往因为与API的胶葛。

皇冠正版app下载

没有被相识的API?一个老码农眼中的API世界 即便做了20多年的软件开辟,仍然发明本身常常会低估完成一个特定的编程任务所需要的时间。有时,错误的时间表是由于本身的能力不足造成的: 当深入研究一个问题时,会发明它比最初想象的要可贵多,因此解决这个问题需要更长的时间ーー这就是法式员的糊口。纵然本身清楚地知道想要实现什么以及如何实现它,还会常常比预期的要花费更多的时间,这种环境往往因为与API的胶葛。

目次 1 无所不在,API 的空间视角 2 杰出与糟糕,API 的真脸孔 3 API 设计的经验性原则 3.1 功效的完整性 3.2 挪用的简朴性 3.3 设计的场景化 3.4 有无计谋性的配置 3.5 面向用户的设计 3.6 推卸责任源于蒙昧 3.7 清晰的文档化 3.8 API的人体工程学 4 机能约定,API的时间视角 4.1 API的机能分类 展开全文 4.2 按机能规划API 4.3 API的机能变化 4.4 API挪用失败时的机能 5 确保API 机能的经验性方法 5.1 审慎地选择API 和法式布局 5.2 在新版本公布时提供一致的机能约定 5.3 防御性编程可以提供帮忙 5.4 API 公然的参数调优 5.5 丈量机能以验证假设 5.6 使用日志检测和记载异常 6 面临API,开辟者的苦恼 6.1 没有 API 6.2 繁琐的注册 6.3 多收费的API 6.4 埋没 API 文档 6.5 糟糕的私有协议 6.6 单一的 API 密钥 6.7 手动维护文档 6.8 忽略运维情况 6.9 非幂等性 7 API 设计中的文化认知 7.1 API意识的训练 7.2 API设计人才的流失 7.3 开放与节制 小我私家认为,此刻所普遍使用的API 与二十年前C语言编写的API 并没有本质的差别。关于API的设计,似乎有些难以捉摸的工具。

API(Application Programming Interface,应用编程接口)是一些预先界说的函数,或软件系统差别构成部门之间的跟尾约定。API 提供了基于软件或硬件得以会见一组例程的能力,而无需使用源代码,也无需理解其内部的事情机制。API(Application Programming Interface,应用编程接口)是一些预先界说的函数,或软件系统差别构成部门之间的跟尾约定。

API 提供了基于软件或硬件得以会见一组例程的能力,而无需使用源代码,也无需理解其内部的事情机制。1 无所不在,API 的空间视角 一看到API,许多人首先想到的是Restful API,基于HTTP协议的网络编程接口。实际上, API的观点外延很大,从微观到宏观,会发明API在计较机的世界里无处不在。

拿起显微镜,假如Rest API 面向的是网络通信,可以想把空间限制在单机上。一台主机上的IPC同样由各类各样的API构成,而一切代码的执行城市归结到系统挪用上来,操作系统提供的系统挪用同样是API。走进操作系统,走进函数指针的API,调解显微镜的镜头,API 可能表现在Jump 指令上,在深入就会进入电路与系统的范畴了。

抬起望远镜,感激通信与网络技能的成长,一切软件都险些演酿成了漫衍式系统。API 成为了漫衍式系统中的血管和枢纽,Restful API 只是 RPC的一种。节点内子系统之间的API通信往往形成了工具流量,节点间子系统之间的API通信形成了南北流量。调解显微镜的镜头,这个系统通过开放平台提供了API,逐渐形成了生态系统。

生态系统间的异构API正在跟着网络世界的延伸而形成新的世界。从空间的视角来看,计较机的世界险些就是通过API毗连的世界。2 杰出与糟糕,API 的脸孔 好的 API给我们带来兴趣,险些可以忽略他们的存在,它们能给对一个特定任务在合理的时间内完成,可以很容易地被发明和影象,有杰出的文档记载,有一个直观的界面使用,并可以或许正确处置惩罚界限条件。

然而,对于每一种正确设计 API 的方法,凡是都有几十种不正确的设计方法。简朴地说,创建一个糟糕的 API 很是容易,而创建一个好的 API 则比力坚苦。纵然是很小很简朴的设计缺陷也有被夸大的倾向,因为 API会被多次挪用。

设计缺陷会导致代码鸠拙或效率低下,那么在挪用 API 的每个点城市呈现由此发生的问题。别的,一个设计缺陷在伶仃的环境下是微小的,但通过彼此感化的方式具有惊人的粉碎性,并迅速导致大量的间接伤害。对于糟糕的 API 设计,后果浩瀚且严重,难于编程,凡是需要编写分外的代码。

假如没有此外原因,这些分外的代码会使法式变大,效率更低,因为每一行不须要的代码城市增加事情荟萃的巨细,并可能减少 CPU 缓存的掷中率。别的,糟糕的API还可能会强制举行不须要的数据复制,或者对预期的成果抛出异常,从本质上发生效率低下的代码。糟糕的API更难理解,也更难使用。面临糟糕的API,法式员编写代码的时间会更长,直接导致了开辟成本的增加。

举个例子,假如一个设计不妥的 API 会导致Microsoft PowerPoint经常瓦解的话,那可能会有海量用户受到影响。雷同地,笔者见过的大量宁静缝隙都是由尺度 c 库(如 strcpy)中不宁静的IO操作或者字符串操作造成的。这些设计缺陷的API,造成的累积成本很容易到达数十亿资金。

从开辟的视角看API的话,大大都软件开辟都是关于差别条理的抽象,而API是这些抽象的可见接口。抽象减少了庞大性, 应用法式挪用较高级此外库,凡是再挪用较初级此外库提供的办事来实现,而较初级此外库又挪用操作系统的系统挪用接口提供的办事。这种抽象条理布局很是强大,没有它,咱们所知道的软件就可能不存在,法式员会被庞大性完全压垮。有悖常理的是,抽象层经常被用来淡化糟糕 API 的影响: “这不重要,我们可以编写一个API来埋没问题。

” 这种说法大错特错,首先,就内存和执行速度而言,纵然是效率最高的API封装也会增加一些成本,其次,原来就是设计杰出的API的份内事情, 凡是环境下,API 封装会发生一系列的问题。因此,只管API的封装可以是糟糕的API可用,这并不料味着这个糟糕的API可有可无,这里没有“负负得正”,不须要的API封装只会导致软件越发臃肿。3 API 设计的经验性原则 有些时候,本身新的认知可能只是别人的知识。在设计 API 的时候 ,有一些经验性原则可以使用。

很遗憾。仍然无法提炼到方法论的高度。3.1 功效的完整性 API要提供完整的功效,这似乎是显而易见的,提供不足功效的 API 是不完整的。

在设计历程中仔细查抄一个功效清单,不停地问本身: “是否有漏掉呢?” 3.2 挪用的简朴性 API 使用的类型、函数和参数越少,进修、影象和正确使用就越容易。很多 API最终成为了助手函数的组合器,C+ + 尺度字符串类及其凌驾100个的成员函数就是一个例子。在使用 C + + 编程多年之后,本身仍然无法在不查阅使用手册的环境下使用尺度字符串来处置惩罚任何重要的工作。

为了很好地设计 API,设计人员必需相识使用 API 的情况,并对该情况举行设计。是否提供一个非根基的便利函数取决于设计者预期这个API被使用的频率。假如频繁使用,就值得添加。

对 API 向下兼容的担心跟着时间的推移而侵蚀 API , API 累积起来最终造成的损害比它保持向后兼容所带来的利益还要大。3.3 设计的场景化 思量一个类,它提供了对一组字符串键值对的会见,好比情况变量: class KVPairs { public string lookup(string name); // ... } lookup方法提供了对定名变量值的会见。显然,假如配置了具有给命名称的变量,函数将返回其值。可是,假如没有配置变量,函数应该如何运行?可能有几种选择: 抛出 VariableNotSet 异常 返回 null 返回空字符串 假如预期查找一个不存在的变量不是一个常见的环境,而且可能视为一个错误,那么抛出异常是适当的。

异常会迫使挪用方处置惩罚错误。另一种环境,挪用者可能查找一个变量,假如没有则替换一个默认值。假如是这样的话,抛出异常完全是错误的,因为处置惩罚异常会粉碎正常的节制流,并且比测试 null 或空返回值更坚苦。

假设假如没有配置变量时不抛出异常,有两个方式表白查找失败: 返回 null 或空字符串。哪一个是更合适呢?同样,谜底取决于预期的场景用例。返回 null 允许挪用者区分没有配置的变量和配置为空字符串的变量,而返回未配置的变量的空字符串使得不行能区分从未配置的变量和显式配置为空字符串的变量。

假如认为可以或许举行这种区分很重要,那么返回 null 是须要的; 可是,假如这种区分不重要,那么最好返回空字符串而且永远不返回 null。3.4 有无计谋性的配置 API 配置计谋的水平对其可用性有着深远的影响 ,只有当挪用者对 API 的使用与设计者预期的场景相一致时,API 才能最优地执行。

假如对将要使用的 API 场景知之甚少,那么只能保持所有选项的开放性,并允许 API 尽可能遍及地应用。实际上,什么应该是错误和什么不该该是错误之间的边界很是细微,并且错误地快速放置这个边界会导致更大的疾苦。

对 API 的配景相识得越多,它可以拟定的计谋就越多。这样做对换用方有利,因为它捕捉了错误,不然就无法检测到这些错误。通过仔细设计类型和参数,凡是可以在编译时捕捉错误,而不是延迟到运行时。

在编译时捕捉的每个错误都减少了一个错误,这个错误可能会在测试期间或出产情况中发生分外的成本。凡是环境下,人们对上下文知之甚少,因为 API 是初级的,或者就其本质而言,必需在很多差别的上下文中事情。在这种环境下,计谋模式往往可以用来取得杰出的效果。

它允许挪用者提供计谋,从而保持设计的开放性。按照编程语言的差别,挪用方提供的计谋可以使用回调、虚函数、署理或模板等来实现。假如 API 提供了合理的缺省值,那么这种外部化的计谋可以在不损害可用性和清晰性的环境下带来更大的机动性。

3.5 面向用户的设计 法式员很容易进入解决问题的模式: 需要什么数据布局和算法来完成这项事情,需要什么输入和输出来完成这项事情?实现者专注于解决问题,而挪用者的存眷点很快被健忘。得到可用 API 的一个好方法是让挪用者编写函数名,并将该API签名交给法式员来实现。仅这一步就至少消除了一半糟糕的API,假如API的实现者从不使用他们本身的API,这对可用性会造成劫难性的后果。

别的,API 与编程、数据布局或算法无关,API 与 GUI 一样,也是一个用户界面。使用 API 的用户是一个法式员,也就是一小我私家。只管倾向于认为API是呆板接口,但它们不是: 它们是人机接口。

驱动 api 设计的不是实现者的需求,这意味着好的 api 是按照挪用者的需求设计的,纵然这会使实现者的事情变得越发庞大。3.6 不推卸责任 “推卸责任”的一种方式是畏惧配置计谋: “好吧,挪用者可能想要这样或那样做,但我不能确定是哪个,所以我会配置它。” 这种方法的典型成果是接纳五个或十个参数的函数。因为设计者没有配置计谋,也不清楚 API 应该做什么和不该该做什么,所以 API 最终的庞大性远远凌驾了须要的水平。

一个好的 API 很清楚它想要实现什么和不想要实现什么,而且不畏惧预先相识它。由此发生的简朴性凡是可以弥补功效的轻微损失,出格是假如 API 具有杰出的根基操作,可以很容易地组合成更庞大的操作。另一种推卸责任的方式是牺牲可用性来提高效率。机能增益是一种错觉,因为它使挪用者“干脏活” ,而不是由 API 执行。

换句话说,可以以零运行时开销提供更宁静的 API。通过仅对 API 内部完成的事情举行基准测试,而不是由挪用方和 API 配合完成的任务 ,设计人员可以声称已经创建了机能更好的 API,是缺乏价值的。即便是内核也不是没有瑕疵,而且偶然会推卸责任。

某些系统挪用会被间断,迫使法式员明确处置惩罚并手动重启被间断的系统挪用,而不是让内核透明地处置惩罚。推卸责任可以采纳很多差别的形式,各类 API 的细节不同很大。对于设计者来说,关键的问题是: 有没有什么可以合理地为挪用者做的工作是我没有做的?假如有,是否有合法来由不这样做?明确地提出这些问题使得设计成为一个有意识的历程,而不是“偶尔的设计”。

3.7 清晰的文档化 API 文档的一个大问题是,它凡是是在 API 实现之后编写的,并且凡是是由实现者编写的。然而,实现者被实现所污染,而且倾向于简朴地写下所做的工作。

这凡是会导致文档不完整,因为实现人员对 API 太熟悉了,而且假设有些工作是显而易见的,而实际上并非如此。更糟糕的是,它常常导致API完全忽略重要的用例。另一方面,假如挪用者编写文档,挪用者可以从用户的角度处置惩罚问题,不受当前实现的影响。这使得 API 更有可能满意挪用者的需求,并防止很多设计缺陷的呈现。

最不适合编写文档的人是API的实现者,最不适合编写文档的时间是在实现之后。这样做会增加接口、实现和文档都呈现问题的可能性。确保文档是完整的,出格是关于错误处置惩罚的文档。当工作堕落时,API 的行为是个中的一部门,也是工作进展顺利时的一部门。

文档是否说明 API 是否维护异常?是否具体说明晰在堕落环境下输出和输入输出参数的状态?是否具体说明晰在错误产生后可能存在的任何副感化?是否为挪用者提供了足够的信息来理解错误?法式员确实需要知道当呈现错误时 API 的行为,而且确实需要得到具体的错误信息,以便通过编程方式举行处置惩罚。单位测试和系统测试对 API也有影响,因为它们可以发明以前没有人想到的工具。测试成果可以帮忙改良文档,从而改良 API,文档是 API 的一部门。

3.8 API的人体工程学 人体工程学自己就是一个研究范畴,也可能是 API 设计中最难确定的部门之一。关于这个主题,已经有了许多内容,比方界说定名约定、代码结构、文档样式等。

除了纯真的时尚问题,切合人体工程学的实现杰出是坚苦的,因为它提出了庞大的认知和心理问题。法式员是人,所以一个法式员认为很好的 API 可能被另一个法式员认为是一般的。

出格是对于大型和庞大的 api,人机工程学涉及到一致性的问题。比方,假如一个 API 老是以沟通的顺序放置特定类型的参数,那么它就更容易使用。雷同地,假如API成立定名法则,将相关函数与特定的定名气势派头组合在一起,那么就更容易使用。

同时, API 为相关任务成立简朴统一的约定并使用统一的错误处置惩罚。一致性不仅使事物更容易使用和影象,并且还可以转移进修。转移进修不仅在API内部很重要,并且在API 之间也很重要。

API之间可以接纳的观点越多,就越容易把握所有的观点。实际上,即便是Unix 中的尺度IO库也在很多处所违背了这一思想。比方,read 和 write 的系统挪用将文件描述符放在第一个参数位置,可是尺度库中如 fgets 和 fputs ,将流指针放在最后,而 fscanf 和 fprintf 又将流指针放在第一个位置。

这时候,往往要感激IDE的代码补全功效了。4 机能约定,API的时间视角 在 API 中挪用函数时,固然期望它们可以或许正确事情,这种期望可以被称为挪用方和实现之间的约定。同时,挪用者对这些功效也有机能期望,软件系统的乐成凡是也取决于满意这些期望的 API。

因此,除了正确性约定之外,另有机能约定。履行合同凡是是隐含的,经常是恍惚的,有时是被违反的(由挪用者或执行者)。如何改良这方面的 API 设计和文档? 当今任何重要的软件系统都依赖于其他人的事情,通过API挪用操作系统和各类软件包中的函数,从而减少了必需编写的代码量。在某些环境下,要把事情外包给长途办事器,这些办事器通过网络与你毗连。

我们既依赖于这些函数和办事来实现正确的操作,也依赖于它们的执行机能以包管整个系统的机能。在涉及分页、网络延迟、共享资源(如磁盘)等的庞大系统中,机能一定会有变化。

然而,纵然是在简朴的配置中,好比在内存中包罗所有法式和数据的独立计较机中,当一个 API 或操作系统达不到机能预期时,也是令人沮丧的。人们习惯于谈论应用法式和 API 实现之间的功效约定。

虽然如今的 API 规范并没有以一种导致正确性证明的方式明确划定正确性的尺度,可是 API 函数的类型声明和文本文档力图对其逻辑行为绝不暗昧。然而,API 函数的意义远不止正确性。

它耗损什么资源,速度有多快?人们经常按照本身对某个函数的实现应该是什么的判断做出假设。遗憾的是,API 文档没有提示哪些函数有机能包管,哪些函数实际上价格奋发。更庞大的是,当应用法式调解到 API 的机能特征之后,一个新版本的 API 实现或者一个新的长途存储办事却削减了软件系统的整体机能。简而言之,从时间的视角来看,API的机能契约值得更多存眷。

4.1 API的机能分类 为了实用有效,从计较庞大度来看,可以对API的机能做一个简朴的分类。恒定的机能 比方 toupper, isdigit, java.util.HashMap.get等。前两个函数老是计较廉价的,凡是是内联表查找。正确巨细的哈希表查找应该也很快,可是哈希冲突可能会偶然减慢会见的速度。

凡是的机能 比方fgetc, java.util.HashMap.put等。很多函数被设计成大大都时候都很快,可是偶然需要挪用更庞大的代码; fgetc 必需偶然读取一个新的字符缓冲区。在哈希表中存储一条新数据可能会使该表变满,以至于会重对表中所有条目举行哈希计较。

java.util.HashMap 在机能约定方面有一个很好的描述: “这个实现为根基操作(get 和 put)提供了常量时间机能,假设散列函数将元素正确地分离在存储桶中。对荟萃视图的迭代,需要与 HashMap ‘容量‘成比例的时间...... “。fgetc 的机能取决于底层流的属性。假如是磁盘文件,那么该函数凡是将从用户内存缓冲区读取,而不需要系统挪用,但它必需偶然挪用操作系统来读取新的缓冲区。

假如是从键盘读取输入,那么实现可能会挪用操作系统来读取每个字符。法式员成立机能模型是基于经验,而不是规范,并非所有函数都有明明的机能属性。

可预期的机能 比方 qsort, regexec等。这些函数的机能随其参数的属性(比方,要排序数组的巨细或要搜索的字符串的长度)而变化。

这些函数凡是是数据布局或大众算法实用法式,使用众所周知的算法,不需要系统挪用。我们凡是可以按照对底层算法的期望来判断机能(比方,排序将花费 nlogn 的时间)。当使用庞大的数据布局(比方 B 树)或通用荟萃(在这些处所可能很难确定底层的详细实现)时,可能更难预计机能。

重要的是,可预测性只是可能的; regexec 基于它的输入凡是是可预测的,可是有一些病态的表达会导致庞大计较的发作。未知的机能 比方fopen, fseek, pthread_create,许多初始化的函数以及所有网络挪用。这些函数的机能经常有很大的差异。

它们从池(线程、内存、磁盘、操作系统对象)分派资源,凡是需要对共享操作系统或 IO资源的独有会见。凡是需要大量的初始化事情, 通过网络举行挪用相对于当地会见老是慢的,这使得合理机能模型的形成变得越发坚苦。线程库是机能问题的简朴标记。Posix 尺度花了许多年才不变下来,然而如今仍然被机能问题所困扰。

线程应用法式的可移植性仍然存在风险,原因是线程需要与操作系统精密集成,险些所有操作系统(包括 Unix 和 Linux)最初设计时都没有思量到线程; 线程与其他库的交互,为了使线程宁静而导致的机能问题等等。4.2 按机能划分API 有些库提供了执行一个函数的多种方法,凡是是因为这些方法的机能不同很大。大大都法式员被奉告使用库函数来获取每个字符并不是最快的方法,更注重机能的人会读取一个大型的字符数组,并使用编程语言中的数组或指针来操作提取每个字符。

在极度环境下,应用法式可以将文件页映射到内存页,以制止将数据复制到数组中。作为提高机能的副感化是,这些函数给挪用方带来了更大的承担。比方,得到缓冲区算法的正确性,挪用 fseek需要调解缓冲区指针和可能的内容。

法式员老是被发起制止在法式中过早地举行优化,从而推迟修订,直到更简朴的做法被证明是不满意要求的。确定机能的独一方法是丈量。法式员凡是在编写完整个法式之后,才碰面对机能期望与所交付的实现之间的不匹配。4.3 API的机能变化 可预测函数的机能可以按照其参数的属性举行预计,未知函数的机能功效也可能因要求它们做什么而有很大的差别。

在存储设备上打开流所需的时间固然取决于底层设备的会见时间,大概还取决于数据传输的速率。通过网络协议会见的存储可能出格昂贵,并且它是变化的。由于各类原因,一般的函数跟着时间的推移变得越来越强大。I/O流就是一个很好的例子,按照打开的流类型(当地磁盘文件、网络办事文件、管道、网络流、内存中的字符串等) ,挪用打开流在库和操作系统中挪用纷歧样的代码。

跟着IO设备和文件类型规模的扩展,机能的差异只会增加。大大都API的配合生命周期是跟着时间的推移慢慢增加功效,从而不行制止地增加了机能变化。

一个很大的变化来历是差别平台的库接口之间的差异。固然,平台的底层速度(硬件和操作系统)会有所差别,可是库接口可能会导致 API 内函数的机能或 API 间的机能变化。有些库(比方那些用于处置惩罚线程的库)的移植机能差异很是大。

线程异常可能以极度行为的形式呈现ーー极其缓慢的应用法式甚至是死锁。这些差异是难以成立准确的API机能约定的原因之一。我们往往不需要很是准确地相识机能,可是预期行为的极度变化可能会导致问题。比方,使用 malloc 函数的动态内存分派可以被描述为“凡是的机能” ,这将是错误的,因为内存分派(尤其是 malloc)是法式员开始寻找机能问题时的首要嫌疑之一。

作为机能直觉的一部门,假如挪用 malloc 数以万计次,出格是为了分派小的固定巨细的块,最好使用 malloc 分派一个更大的内存块,将其支解成固定巨细的块,并办理本身的空闲块列表。Malloc 的实现多年来一直在积极让它变得高效,提供虚拟内存、线程和很是大的内存的系统都对malloc 和free组成了挑战,必需衡量某些使用模式(如内存碎片)的效率和毛病。一些软件系统,如Java,使用自动内存分派和垃圾收集来办理空闲存储。

虽然这是一个很大的便利,可是一个体贴机能的法式员必需意识到成本。比方,一个 Java 法式员应该尽早被奉告 String 对象和 StringBuffer 对象之间的区别,String 对象只能通过在新内存中创建一个新的副原来修改,而 StringBuffer 对象包罗容纳字符串可以耽误的空间。跟着垃圾收集系统的改良,它们使得不行预知的垃圾收集暂停变得不那么常见; 这可能会让法式员骄傲,相信自动回收内存永远不会成为机能问题,而实际上这就是一个机能问题。

4.4 API挪用失败时的机能 API的规范包括了挪用失败时的行为。返回错误代码和抛出异常是告诉挪用方函数未乐成的常用方法。可是,与正常行为的规范一样,没有指定妨碍的机能。

主要有以下是三种形式: 快速失败。一个API挪用很快就失败了,和它的正常行为一样快或者更快。比方,挪用 sqrt (- 1)会很快失败。

纵然当一个 malloc 挪用因为没有更多的内存可用而失败时,这个挪用也应该像任何 malloc 挪用一样快速地返回,因为后者必需从操作系统请求更多的内存。为了读取一个不存在的磁盘文件而打开一个流的挪用很可能与乐成挪用返回的速度一样快。

逐步失败。有时,一个API挪用失败的速度很是慢,以至于应用法式可能但愿以其他方式举行。比方,打开到另一台计较机的网络毗连请求只有在频频长时间超时后才会失败。

永远失败。有时候一个API挪用只是暂停,底子不允许应用法式继续运行。比方,其实现等候从未释放的同步锁的挪用可能永远不会返回。一个勤奋的法式员会尽可能处置惩罚不行能的失败。

一种常见的技能是用 try... catch 块困绕法式的大部门,这些块可以重试失败的整个部门。交互式法式可以实验生存用户的事情,捕捉周围的整个法式,其效果是减轻失败的主法式造成的损失,比方生存在一个磁盘文件,关键日志或数据布局等等。处置惩罚暂停或死锁的独一方法可能是配置一个watchdog线程,该线程期望按期查抄一个正常运行的应用法式,假如康健查抄异常,watchdog就会采纳动作,比方,生存状态、中止主线程和从头启动整个应用法式等。

假如一个交互式法式通过挪用可能缓慢失败的函数来响应用户的号令,它可能会使用watchdog终止整个号令,并返回到允许用户继续执行其他号令的已知状态,这就发生了一种防御性的编程气势派头。5 确保API 机能的经验性方法 法式员按照对 API 机能的期望选择 API、数据布局和整个法式布局。假如预期或机能严重错误,法式员不能仅仅通过调优 API 挪用来恢复,而必需重写法式(可能是主要部门)。

前面提到的交互式法式的防御布局是另一个例子。固然,有很多法式的布局和机能很少受到库机能的影响(科学计较和大型模拟凡是属于这一类)。

然而,今天的很多“通例 IT” ,出格是广泛基于 web 的办事的软件,遍及使用了对整体机能至关重要的库。纵然机能上的微小变化也会导致用户对法式的感知产生重大变化,在处置惩罚各类媒体的节目中尤其如此。

偶然放弃视频流的帧可能是可接管的 ,可是用户可以感知到音频中哪怕是轻微的间断,因此音频媒体机能的微小变化可能会对整个节目的可接管性发生重大影响。这种担心引起了人们对办事质量的极大乐趣,在很多方面,办事质量是为了确保高程度的业绩。

只管违反机能契约的环境很少,并且很少是劫难性的,但在使用软件库时注意机能可以帮忙构建更健壮的软件。以下是一些经验性原则: 5.1 审慎地选择API 和法式布局 假如有幸重新开始编写一个法式,那么在开始编写法式时,要思量一下机能约定的寄义。假如这个法式一开始只是一个原型,然后在办事中保持一段时间,那么毫无疑问它至少会被重写一次; 重写是一个从头思考 API 和布局选择的时机。5.2 在新版本公布时提供一致的机能约定 一个新的尝试性 API 会吸引那些开始衍生 API 机能模型的用户。

今后,更改机能约定必定会激愤开辟人员,并可能导致他们重写本身的法式。一旦 API 成熟,机能约定稳定就很重要了。事实上,大大都通用 API (比方 libc)之所以变得如此,部门原因在于它们的机能约定在 API 成长历程中是不变的。

同样的原理也合用于 api 端口 人们可能但愿 API 提供者可以或许按期测试新版本,以验证它们没有引入机能怪癖。不幸的是,这样的测试很少举行。可是,这并不料味着不能对依赖的 API 部门举行本身的测试。

使用阐发器,凡是可以发明法式依赖于少量的API。编写一个机能测试东西,将一个API的新版本与早期版本的记载机能举行比力,这样可以给法式员提供一个早期预警警,即跟着API新版本的公布,他们本身代码的机能将产生变化。很多法式员但愿计较机及其软件可以或许一致地跟着时间的推移而变得更快。

这实际上对于供给商来说是很难包管的,可是它们会让客户相信是这样的。很多法式员但愿图形库、驱动法式和硬件的新版本可以或许提高所有图形应用法式的机能,并热衷于多种功效的改良,这凡是会降低旧功效的机能,哪怕只是轻微的降低。我们还可以但愿 API 规范将机能约定明确化,这样使用、修改或移植代码的人就可以遵守约定。

注意,函数对动态内存分派的使用,无论是隐式的还是自动的,都应该是API文档的一部门。5.3 防御性编程可以提供帮忙 在挪用机能未知或高度可变的 API 时,法式员可以使用特殊的方式,对于思量妨碍机能的环境尤其如此。我们可以将初始化移到机能关键区域之外,并实验预加载API 可能使用的任何缓存数据(比方字体)。

体现出大量机能差异或拥有大量内部缓存数据的 API ,可以通过提供帮忙函数将关于如何分派或初始化这些布局的提示从应用法式通报给 API。某个法式偶然会向办事器发出 ping 信号,这可以成立一个可能不行用的办事器列表,从而制止一些长时间的妨碍暂停。

5.4 API 公然的参数调优 有些库提供了影响机能的明确方法(比方,节制分派给文件的缓冲区的巨细、表的初始巨细或缓存的巨细),操作系统还提供了调优选项。调解这些参数可以在机能约定的规模内提高机能,调优不能解决总体问题,但可以减少嵌入在库中的固定选项,这些选项会严重影响机能。

有些库提供了具有沟通语义函数的替代实现,凡是是通用API的详细实现形式。通过选择最好的详细实现举行调优凡是很是容易,Java 荟萃就是这种布局的一个很好的例子。

越来越多的API被设计成动态地适应应用,使法式员无需选择最佳的参数配置。假如一个散列表太满,它会自动扩展和从头哈希(这是一种长处,但偶然会降低机能)。

假如文件是按顺序读取的,那么可以分派更多的缓冲区,以便在更大的块中读取。5.5 丈量机能以验证假设 常见方式是检测关键数据布局,以确定每个布局是否正确使用。比方,可以丈量哈希表的完整水平或产生哈希冲突的频率。或者,可以验证一个以写机能为价格的快速读取布局实际上被读取的次数多于被写入的次数。

所有这些都不是为了阻止完美主义者开辟自动化仪表盘和丈量的东西,或者开辟具体说明机能约定的方法,以便机能丈量可以或许成立对机能约定的遵守。这些方针并不容易实现,回报可能也不会很大。

凡是可以在不事先检测软件的环境下举行机能怀抱,长处是在呈现需要跟踪的问题之前不需要任何事情还可以帮忙诊断当修改代码或库影响机能时呈现的问题。按期举行提要阐发,从可信赖的基础上权衡机能偏差。

5.6 使用日志检测和记载异常 当漫衍式办事构成一个庞大的系统时,会呈现越来越多的违反机能约定的行为。注意,通过网络接口提供的办事有时具有指定可接管机能的SLA。在很多设置中,怀抱历程偶然会发出办事请求,以查抄 SLA 是否满意。由于这些办事使用雷同于 API 挪用的方法(比方,长途历程挪用或其变体,如 XML-RPC、 SOAP 或 REST),因此可能是有机能约定的期望。

应用法式会检测这些办事的失败,而且凡是会应对恰当。然而,响应缓慢,出格是当有很多这样的办事互相依赖时,可能会很是快地粉碎系统机能。

假如这些办事的客户可以或许记载他们所期望的机能,并生成有助于诊断问题的日志(这就是 syslog 的用途之一) ,那将会很有帮忙。当文件备份看起来不合理的慢,那是不是比昨天慢呢?比最新的操作系统软件更新之前还要慢?思量到多台计较机可能共享的备份设备,它是否比预期的要慢?或者是否有一些合理的解释(比方,备份系统发明一个损坏的数据布局并开始一个长的历程来从头构建它) ? 在没有源代码,也没有组成组合的模块和API的细节的环境下,诊断不透明软件组合中的机能问题可以在陈诉机能和发明问题方面发挥感化。

虽然不能在软件内部解决机能问题 ,可是可以对操作系统和网络举行调解或修复。假如备份设备由于磁盘险些已满而速度较慢,那么必定可以添加更多的磁盘空间。

好的日志和相关的东西会有所帮忙; 遗憾的是,日志在计较机系统演进中可能是一个被低估和忽视的范畴。诚然,机能约定没有功效正确性约定那么重要,可是软件系统的重要用户体验险些都取决于它。6 面临API,开辟者的苦恼 对于向外部提供的API,有一些因素成为了开辟者的苦恼。6.1 没有 API API 允许客户实现你没有想到的功效,允许客户更多的使用产物。

假如存在一个API,开辟者可以自动使用API的产物,这将发生更多的应用。他们可以自动化整个公司的设置,可以基于你的 API 构建全新的应用法式。

只要想想他们可以或许通过 API 使用几多产物就可以了。6.2 繁琐的注册 只有庞大的注册历程才能包管API的宁静么?实际上只是自寻烦恼。

要么使整个历程完全自助办事,要么底子不需要任何类型的注册历程,这样才是杰出的API使用初步 6.3 多收费的API 对办事收费是正常的,或者只在“企业版”中包罗 API 会见。让 API 会见变得如此昂贵,以至于销售部分认为 API 代表分外的利润激励。事实上,API 不该该成为一种收入来历,而是一种勉励人们使用产物的方式。

6.4 埋没 API 文档 没有什么比在搜索引擎中看不到API 文档更糟糕的事了。那些将API文档放在登录之后的体验屏幕后面,可以认为是设计人员的大脑短路。通过某种注册或登录来阻止竞争敌手检察API 并从中进修,这是一种幼稚的想法。

6.5 糟糕的私有协议 一个私有协议可能很难理解,也不行能调试。SOAP可能会变得臃肿和过于冗长,从而导致带宽耗损和速度减慢。它也是基于 XML 的,尤其是在移动或嵌入式客户端上,解析和操作起来很是昂贵。

很多 API 使用 JSON API 或 JSON-rpc ,它们是轻量级的,易于使用,易于调试。6.6 单一的 API 密钥 假如只允许使用一个 API 密钥,相当于创建了一个“第22条军规”的环境。开辟者无法更改办事器上的 API 密钥,因为客户端也会在更新之前失去了会见权限。

他们也不能首先更改客户端,因为办事器还不知道新的 API 密钥。假如有多个客户端,那根基上就是一场劫难。6.7 手动维护文档 跟着 API 的成长,API 和文档有可能离开同步。

一个错误的API说明会导致一个无法事情的系统,会令人极其的沮丧。一个与文档差别步的 API,会让人束手无策。

6.8 忽略运维情况 将基础设施视为代码的能力正在成为运维团队的要事。它不仅使操作更容易、更可测试和更靠得住,并且还为诸如付出行业所要求的宁静性最佳实践铺平了门路。假如忽略了Ansible, Chef, Puppet等雷同的系统,可能会导致一系列令人狐疑的不兼容选项,使得出产情况的API挪用难觉得继。

6.9 非幂等性 假设有一个创建虚拟机的 API 挪用。假如这个 API 挪用是幂等的,那么我们第一次挪用它的时候就创建了 VM。第二次挪用它时,系统检测到 VM 已经存在,并简朴地返回,没有错误。

假如这个 API 挪用长短幂等的,那么挪用10次就会创建10个 vm。为什么有人要多次挪用同一个 API?在处置惩罚 rpc时,响应可能是乐成、失败或底子没有应答。

假如没有收到办事器的答复,则必需重试请求。使用幂等协议,可以简朴地重发请求。

对于非幂等协议,每个操作后都必需追随发明当前状态并举行正确恢复的代码,将所有恢复逻辑放在客户机中是一种丑恶的设计。将此逻辑放在客户机库中可以确保客户端需要更频繁的更新,要求用户实现恢复逻辑是令人难熬的。当 API 是幂等的时候,这些问题就会减少或消除。假如网络是不行靠的,那么网络 API 本质上也是不行靠的。

请求可能在发送到办事器的途中丢失,并且永远不会执行。执行可能已经完成,可是答复的信息已经丢失了。

办事器可能在操作期间从头启动。客户端可能在发送请求时从头启动,在等候请求时从头启动,或者在吸收请求时从头启动,在当地状态存储到数据库之前从头启动。

在漫衍式计较中,一切都有可能失败。法式员们以做好事情和完善的系统给用户留下深刻印象而高傲,令开辟者苦恼的API往往出于蒙昧、缺乏资源或者不行能的最后期限。7 API 设计中的文化认知 假如让API 的设计可以做得更好的话,除了一些细节性的技能问题外,还可能需要解决一些文化问题。我们不仅需要技能聪明,还需要改变我们认识和实践软件工程的方式。

7.1 API的有意识训练 本身读书的时候,法式员的培训主要偏重于数据布局和算法。这意味着一个称职的法式员必需知道如何编写各类数据布局并有效地操作它们。

跟着开源运动的成长,这一切都产生了巨大的变化。如今,险些所有可以想象到的可重用功效都可以使用开放源码。因此,创建软件的历程产生了很大的变化,今天的软件工程不是创立功能,而是集成现有的功效或者以某种方式从头封它。换句话说,此刻的 API 设计比20年前越发重要,不仅拥有了更多的 API,并且这些 API 提供了比以前越发富厚且庞大的功效。

从来没有人操心去解释如何决定某个值应该是返回值还是输出参数,如安在激发异常和返回错误代码之间做出选择,或者如何决定一个函数修改它的参数是否合适。所以,期望法式员擅长一些他们从未学过的工具是不合理的。

然而,好的 API 设计,纵然很庞大,也是可以训练的,关键是认识到重要性并有意识的训练。7.2 API设计人才的流失 一个老码农环视附近,才发明周围是何等的不寻常: 所有的编程同事都比我年青,当本身以前的同事或者同学,大大都人不再写代码; 他们转到了差别的岗亭好比各类司理、总监、CXO ,或者完全脱离了这个行业。这种趋势在软件行业随处可见: 年长的法式员很少,凡是是因为看不到职业生涯。

假如不进入办理层,将来的加薪险些是不行能的。一种概念认为,年长法式员的职业优势在不停丧失。这种想法可能是错误的: 年长的法式员可能不会像年青人那样熬夜,但这并不是因为他们年龄大,而是因为许多时候他们不消熬夜就能完成事情。老法式员的流失是不幸的,出格是在 API 设计方面。

虽然好的 API 设计是可以进修的,可是经验是无法替代的。需要时间和不停的挖坑填坑才会做得更好。

不幸的是,这个行业的趋势恰恰是把最有经验的人从编程中提拔出来。另一个趋势是公司将最好的法式员晋升为设计师或系统架构师。凡是环境下,这些法式员作为参谋外包给各类各样的项目,目的是确保项目在正确的轨道上起步,制止在没有参谋聪明的环境下犯错误。

这种做法的意图值得歌颂,但其成果凡是是发人深省的: 参谋从来没有履历过本身的设计决议的后果,这是对设计的一种讽刺。让设计师保持敏锐和务实的方法是让他们吃本身的狗粮, 剥夺设计师反馈的历程最终可能注定失败。7.3 开放与节制 跟着计较的重要性不停增长,有一些API的正确功效险些是无法描述的。

比方, Unix 系统挪用接口、 C尺度库、 Win32或 OpenSSL。这些 API的接口或语义的任何改变城市带来巨大的经济成本,并可能激发缝隙。

允许单个公司在没有外部节制的环境下对如此关键的API举行更改是不卖力任的。严格的立法节制和更开放的同行审查相联合,在两者之间找到得当的均衡对于计较机的将来和网络经济至关重要。API设计确实很重要,因为整个计较机世界都是由API毗连的。

然而,证明实现杰出API所需的投入产出比可能是坚苦的,出格是当一个 API 没有被客户使用的时候。“当险些没有人使用我们的 API 时,收益是几多? ” 产物司理或者老板们常常可能会问这样的问题。

呵呵,也许你没有做过这些工作,所以使用率很低。作者 | 半吊子全栈工匠 来历 | 喔家ArchiSelf(ID:wireless_com) 点亮在看是承认,分享转发是支持返回,检察更多。


本文关键词:澳门皇冠棋牌娱乐平台,没,有被,相识,的,API,一个,老码,农眼,中的,没

本文来源:皇冠正版app下载-www.xianzhibao.net