阅读更多

1顶
0踩

编程语言

转载新闻 如何做到API兼容

2011-06-23 11:30 by 见习记者 lihuapi 评论(0) 有3975人浏览

本文主要介绍什么是API,以及API兼容的重要性,最终给出方案如何评估API,以及如何做到API兼容。

What’s API?

API的全称是application programming interface。

而很多时候,程序开发者仅仅把函数、类的接口做为API的一部分,而忽略了其他重要的编程接口。

事实上,在前端Javscript编程中常见的API包括:

  • 函数、类接口,包括参数,返回值,函数对外部对象(常常是DOM)的具体操作等
  • 网络接口协议,如和后端交互的JSON、XML数据格式,或者script回调中的函数名
  • 样式以及HTML接口
  • 外部依赖(对浏览器具体特性的依赖)
  • 一些无意泄露的内部实现
  • 越往后的API,越隐晦,越不容易受到重视,但是一旦这些API发生变化,可能会导致调用方出现不符合预期甚至程序直接报错的情况。


Why API cannot be changed?

API是程序协同开发的重要保证,API的用户希望API的提供方提供的是一段功能明确、接口明了的程序。更重要的是,用户更期望在程序升级以后,他们能够“不经思考”地升级这些第三方代码。

一旦上述提到的5个API中的任何一个发生变化,可能会给他们带来巨大的代价,用户需要排查所有调用的代码,需要更改一些协议,需要调整所有与之相关的部分,这些工作对他们来说都是额外的,在预期之外的。如果辛辛苦苦完成这些以后,还在测试过程中发现了相关的bug,那对用户的打击就更大了。

如果API经常发生变化,用户就会失去对这段程序的信任,他们会更倾向自己获得源代码以后,按照自己的需求进行修改,自行维护一个内部的API比调用一个不断发生变化的外部API要容易接受的多,虽然这样做和我们协同开发、模块化开发的初衷是完全相悖的。

最后,我们为什么要修改API呢?为了API看起来更加漂亮?为了提供更多有趣的功能?还是仅仅我们觉得到了改变了时候了?对于用户来说,他们更愿意使用一个稳定但是看起来不那么时髦的API,而不是使用一个很时髦,但是会经常变动的API。在这个问题上,项目开发者是实用派。但这并不意味着我们不再改进API了,在后面,我会具体介绍如何能让API保持稳定的同时,让API持续改进。

Quality of API

在正式说兼容性之前,首先要明确一下,什么是好的API,因为导致API的不兼容的根源总是来自一个想法:“期望通过这次改变把API变得更好”。

容易理解
如果一个API不能让大多数使用者快速学会,这一定不是一个好的API。 比如iOS的滑动解锁,老人和小孩都能都能一次解锁,而Nokia的经典两键解锁,你懂的。

一致性
一致性能大大降低用户的学习和使用成本,用户过去的努力学习,能持续的收效。

容易查找和学习
API必须要有文档,并且介绍清晰,提供尽可能多的示例和可copy-paste的代码,降低用户的使用门槛。

提供简单的方案
API要能解决复杂的问题,提供很多可配置项,但是对于那些最常见的case,如果有一个简单的方案供给用户使用,这样能大大提高API的可用性

保护用户在API上的已有工作
用户过去在调用API、基于API开发所做的工作,这样才能给用户带来价值的同时,不破坏他们过去的劳动成果。

如何保证API的兼容

采用良好的设计思路

在设计过程中,如果能按照下面的方式来进行设计,会让这个API生命更长久

  • 面向用例的设计,收集用户建议,把自己模拟成用户,保证API设计的易用和合理
  • 保证后续的需求可以通过扩展的形式完成
  • 第一版做尽量少的内容,由于新需求可以通过扩展的形式完成,因此尽量少做事情是抑制API设计错误的一个有效方案
  • 对外提供清晰的API和文档规范,避免用户错误的使用API,尤其是避免API(见第一节)靠后级别的API被用户知晓与误用

除此之外,下面还列出了一些具体的设计方法:

  • 方法优于属性
  • 工厂方法优于构造函数
  • 避免过多继承
  • 避免由于优化或者复用代码影响API
  • 面向接口编程
  • 扩展参数应当是便利的
  • 对组件进行合理定位,确定暴露多少接口
  • 提供扩展点
  • 有效的API评审


API设计完成以后,需要经过周密的设计评审,评审的重点如下:

  • 用例驱动,评审前必须提供完善的使用用例,确保用例的合理性和完备性。
  • 一致性,是否与系统中其他模块的接口风格一致,是否与对称接口的设计一致。
  • 简单明了,API应该简单好理解,容易学习和使用的API才不容易被误用,给我们带来更多的麻烦。
  • API尽可能少,如果一个API可以暴露也可以不暴露,那么就不要暴露他,等到用户真正有需求的时候再将它成为一个公开接口也不迟。
  • 支持持续改进,API是否能够方便地通过扩展的方式增加功能和优化。
  • 把握API的生命周期


每一个API都是有生命周期的,我们需要让API的生命周期更长,并且在API的生命周期结束时能让其平滑的消亡。

  • 告诉用户我们是如何设计的,避免误用,提供指导,错误的使用往往是缩短API寿命的一大杀手
  • 提供试用期,API不可能一开始就是稳定,经过试用的API才能有更强的生命力
  • 为API分级:内部使用;二次开发使用;开发或试用中;稳定;弃用API。避免API被滥用的同时,我们可以通过调整API的级别,来扩大其影响力,也能更优雅的结束一个API的生命周期。
  • 保持API的逐步改善。


过去我们总希望能将现有的“不合理”的设计完全推翻,然后按照现在“美好”的思路,重新设计这个API,但是在一段时间以后,又会碰到一样的状况,需要再推翻一次。 如果我们没有有效的逐步改善的办法,依靠推翻现有设计,重新设计API只能让我们回到起点,然后重现之前的过程。 要有一套行之有效的持续改善的办法来在API兼容的同时,改善API使之更好。

提高API的可测试性

API需要是可测试的,测试不应依赖实现,测试充分的API,尤其是经过了严格的“兼容性整合测试”(见下文)的API,更能保证在升级的过程中不出现兼容性问题。

兼容性整合测试,是指一组测试用例集合,这组测试用例会站在使用者的立场上使用API。在API升级以后,再检测这组测试用例是否能完全符合预期的通过测试,尽可能的发现兼容性问题。

避免极端的意见

在设计API的时候,一定要避免任何极端的意见,尤其是以下几点:

  • 必须漂亮(API一定要漂亮吗?前文已经说过了)
  • API必须被正确地使用(用户很难理解如何正确的使用API,API的设计者要充分考虑API被误用的情况:如果一个API可能会被误用,那么它一定会被误用)
  • 必须简单(我们总会面临复杂的需求,能两者兼顾的API是更好的API)
  • 必须高性能(性能可以通过其他手段优化,不应该影响API的设计)
  • 必须绝对兼容(尽管本文一直提到如何保证兼容,但是我们仍然要意识到,一些极少情况下会遇到的不兼容是可以容忍的)
  • 一些具体的实施方案


在一个API不可避免要消亡或者改变的时候,我们应该接受并且面对这个事实,下面列举了几种保证兼容性的前提下,对API进行调整的办法:

  • 将API标记为弃用,重新建立一个新的API。如果一个API不可避免要被消亡,这是唯一的办法。
  • 为其添加额外的参数或者参数选项来实现功能添加
  • 将现有API拆成两部分,提供一个精简的核心API,过去的API通过封装核心API上实现。这通常用于解决用户需要一个代码精简的版本时。
  • 在现有的API基础上进行封装,提供一个功能更丰富的包或者类

小结

设计一个保持兼容的API是很困难的。在这之前,作者需要理解什么是API,以及如何评估API的质量以后,通过良好的设计思路以及改进方法,来保证API的向后兼容。

其他
事实上,Tangram base库自从1.3.4版本以后,就已经做到了API的向后兼容,如果对Tangram感兴趣,可以前往Tangram网站查阅。
来自: baiduux
1
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 向下兼容的API版本筛选器

    向下兼容的API版本筛选器 通过注解的方式优雅的实现接口版本向下兼容,针对日常线上接口版本迭代提供了可靠的解决方案,已经历大量的线上验证,可靠!

  • (三)Boost库之字符串处理

    2019独角兽企业重金招聘Python工程师标准>>> ...

  • Boost 入门02(字符串操作)

    字符串操作 使用boost库进行字符串的操作,主要通过引入<boost/algorithm/string.hpp>,来提供操作支持。 字符串切割boost::algorithm::split() #include <boost/algorithm/string.hpp> #include <string> #include <vector> #include <iostream> using namespace boost::algorithm;

  • boost常用字符串处理方法学习

    boost库关于字符串处理的主要是

  • boost字符串库简单使用

    boost字符串库简单使用说明用法大小写转换 说明 写c++程序的时候,虽然std::string有数百余函数,然而仍不能满足很多需要,对字符串的处理不如其他语言方便简洁(例如字符串的分割、字符串转换到大写字母的函数),Boost C++ 库试图弥补这一缺憾,这里简单介绍boost字符串库经常用到的地方。 用法 头文件添加 #include<boost/algorithm/string.hp...

  • boost.string_algo - 字符串算法库 使用点滴

    用来记录零碎的知识,防止自己忘了 判断一个字符串是否全为数字:boost::all( str, boost::is_digit() );

  • 程序员该如何做到API兼容

    本文主要介绍什么是API,以及API兼容的重要性,最终给出方案如何评估API,以及如何做到API兼容。 Whats API? API的全称是application programming interface。 而很多时候,程序开发者仅仅把函数、类的接口做为...

  • 关于HTML5+ API plusready的兼容问题

    Android平台提前注入5+ API,支持在plusready事件前调用 在5+ Runtime环境中,通常情况下需要html页面解析完成后才会注入5+ API,执行的顺序为: 1. 加载html页面 2. 解析html页面(下载script/link等节点引用的资源...

  • 深入C++中API的问题详解

    并不是所有的签名都是API的一部分,未公开的部分(private)内容不是API,它不对外承诺兼容性。API广泛定义:凡是有利于在“无绪”的状态下把一个大的系统以组件集成的方法拼装出来的东西都属于API。为什么要开发API?...

  • Boost库的字符串处理算法

    C++中的字符串类型 说起C++中的字符串类型当仁不让的自然就是std::string。std::string是模板std::basic_string的一个实例化,另外还有三个实例化std::wstring、std::u16string、std::u32string,不过不是很常用。 std::basic_stringT> std::string

  • C++ boost库教程(三):boost字符串处理

    boost库也提供了和STL一样的字符串处理方法,不过比STL更加丰富,使用boost的字符串处理方法,需要包含头文件: #include <boost/algorithm/string.hpp> using namespace boost; boost库有很多以“i”开头,"_copy"结尾的函数方法,简述如下: (1...

  • boost 处理字符串

    boost::algorithm学习 #include using namespace std; using namespace boost;  一:大小写转换 1 to_upper() 将字符串转为大写  Example:  string str1(" hello world! ");  to_upper(str1);  // str1 == " HELLO WORLD! "

  • Boost库:字符串操作

    结合Boost官网 由于这一章内容过多,我将采用四个小章,精简原文四个小部分内容。 第四小章还包含了题目及讲解。 区域设置: setlocale(LC_ALL,“”) locale::global(std::locale("German")); //设置全局区域德语环境 字符串操作: 一、将字符串所有字符转成大写 boost::algorithm::to_upper("")//自身转化 boost::algorithm::to_upper_co..

  • Boost库之字符串处理

    字符串处理一直是c/c++的弱项,string_algo库很好的弥补了这一点。 string_algo 库算法命名规则:  前缀i    : 有这个前缀表名算法的大小写不敏感,否则大小写敏感  后缀_copy:  有这个后缀表明算法不变动输入,返回处理结果的拷贝,否则算法原地处理  后缀_if  :  有这个后缀表明算法需要一个作为判断式的谓词函数对象,否则使用默认的判断准则 s

  • 快速解决docker-py api版本不兼容的问题

    最近打算用docker SDK for Python(以下简称docker-py)做点东西,本来以为按照官网上的步骤安装很简单,pip install docker 就行,然而出现了版本不兼容的问题。 报错如下: docker.errors.APIError: 400 Client ...

  • Android 高版本API方法在低版本系统上的兼容性处理

    本文以一个具体的例子说明如何在使用高API level的方法时处理好兼容性问题。 例子:根据给出路径,获取此路径所在分区的总空间大小。 在安卓中的文件存储使用参考中提到: 获取文件系统用量情况,在API level 9及其...

  • 前端WebAPI,节点样式属性兼容性

    此文档为Xmind格式,主要讲了关于webAPI,涉及到了节点操作,样式及内容操作,属性操作,事件操作,以及兼容性等问题。

  • 一种Api兼容性检测方案

    一般来说,SDK依赖库的Api兼容性问题一直是个隐藏的问题,通常没有很好的方式解决,即使使用语义化版本管理,在众多基础SDK的引用依赖下,不能100%保证其中一个基础SDK的Api发生不兼容的改变后,该改变可能是对外...

  • polyfill处理浏览器API兼容

    polyfill是一段代码插件,处理浏览器兼容问题,一般写在webpack配置文件的入口位置。工作原理:首先检查浏览器是否支持某个API,如果不支持则加载对应的 polyfill,比如IE低版本中增加XMLHttpRequest,内部靠...

Global site tag (gtag.js) - Google Analytics