应用程序接口API是什么
接口是一个抽象概念,一般有好几种层面的接口。Interface可翻译为界面也可翻译为接口,翻译为接口的由来应该是从电器的插口而来(未做考证)。通俗说法:接口就是用来连接而开放的入口。大致有这些类型的接口:硬件接口、用户界面(UI)、软件接口、面向对象接口。
至于API一般仅仅限于应用程序的编程接口。通俗的解释应该是:一个组件(或程序库)提供给开发者进行编程使用的,通过代码可以与之沟通的入口。比如说你下载了一个控件包,通过阅读说明你知道应该如何创建上下文、初始化、设置属性、调用、回调、事件处理,这些就是这个控件包的API。
API一般对应函数,在面向对象领域可能对应类提供的特性,而对于传输协议一般指协议的一种实现所提供的使用该协议的方式。
返回值 方法名(参数1, 参数2 。。。) 这就可以认为是接口。https://console./console/index.php?i=Noah
应用程序接口为:“‘计算机操作系统(Operating system)’或‘程序库’提供给应用程序调用使用的代码”。其主要目的是让应用程序开发人员得以调用一组例程功能,而无须考虑其底层的源代码为何、或理解其内部工作机制的细节。API本身是抽象的,它仅定义了一个接口,而不涉入应用程序如何实现的细节。例如,图形库中的一组API定义了绘制指针的方式,可于图形输出设备上显示指针。当应用程序需要指针功能时,可在引用、编译时链接到这组API,而运行时就会调用此API的实现(库)来显示指针。
应用程序接口API,就是软件系统不同组成部分衔接的约定。由于近年来软件的规模日益庞大,常常需要把复杂的系统划分成小的组成部分,编程接口的设计十分重要。程序设计的实践中,编程接口的设计首先要使软件系统的职责得到合理划分。良好的接口设计可以降低系统各部分的相互依赖,提高组成单元的内聚性,降低组成单元间的耦合程度,从而提高系统的维护性和扩展性。应用程序接口是一组数量上千、极其复杂的函数和副程序,可让程序员做很多任务作,譬如“读取文件”、“显示菜单”、“在视窗中显示网页”等等。操作系统的API可用来分配存储器或读取文件。许多系统应用程序借由API接口来实现,像是图形系统、数据库、网络Web服务,甚至是在线游戏。应用程序接口有诸多不同设计。用于快速执行的接口通常包括函数、常量、变量与数据结构。也有其它方式,如通过解释器,或是提供抽象层以屏蔽同API实现相关的信息,确保使用API的代码无需更改而适应实现变化。
应用程序接口经常是软件开发工具包(SDK)的一部分
API又分为(Windows、Linux、Unix等系统的)系统级API,及非操作系统级的自定义API。作为一种有效的代码封装模式,微软Windows的API开发模式已经为许多商业应用开发的公司所借鉴,并开发出某些商业应用系统的API函数予以发布,方便第三方进行功能扩展。如Google、苹果电脑公司,以及诺基亚等手机开发的API等等。
关于API使用
网上有很多API教程,但是都是针对单个API的使用来讲解,但是如果遇到网上没有教程的API呢?如下教程的目的就是这样:当遇到一个不会的API的时候,懂得如何利用资料学会使用这个API。
本文读者需具备的知识:
1、VB的基本语法
2、API、结构体、常数
3、VB的数据类型,C语言的简单数据类型
4、API Viewer (或其他同类软件)的基本使用
5、一定的英文阅读能力
那么要调用一个陌生的API,基本上遵循以下步骤
1、找到相关API、结构体、常数的声明
2、到MSDN阅读这个API的网页指南
3、按照MSDN写代码
实战演示:
这次实战的目标是:GetOpenFileName
首先介绍一下这个API吧,这个API会显示一个打开对话框,给用户选择一个文件打开
这个跟CommonDialog里面的打开对话框是一样的(那干嘛不直接用那个控件?教程用来做演示嘛,而且用API也有他的好处)
第一步:找到声明
找声明主要有两种方法
第一种是通过软件找,例如API Viewer ,这类软件内置有绝大部分常用的声明,直接复制即可,方便快捷
第二种是去MSDN找到API的页面,然后复制声明。MSDN是微软的网站,声明肯定是准确的,但是对于VB开发者的劣势是,绝大部分声明都是按照C语言的格式的(至今没见过一个API的页面有VB声明),所以如果不懂C语言的话要转换成VB的声明难度就大了
还有其他方法,例如dump dll文件之类的
本文主要讨论第一种方法,使用的软件是API Viewer ,其他同类软件操作大同小异
打开API Viewer ,打开Win32api.apv文件,然后选择Declarations一栏,然后选择Subs and Functions,在文本框输入GetOpenFileName,然后就找到这个API的声明了,复制下来,扔进VB的代码里面
好了,现在来仔细看一下这个声明:
Private Declare Function GetOpenFileName Lib “comdlg32.dll” Alias “GetOpenFileNameA” (ByRef pOpenfilename As OPENFILENAME) As Long
可以看到这里有一个陌生的参数类型OPENFILENAME,这明显不是VB的基本数据类型,所以我们需要这个OPENFILENAME的声明
于是回到API Viewer ,选择Types一栏,在文本框输入OPENFILENAME,找到声明了,复制下来,扔到VB代码里面
Private Type OPENFILENAME
lStructSize As Long
hwndOwner As Long
hInstance As Long
lpstrFilter As String
lpstrCustomFilter As String
nMaxCustFilter As Long
nFilterIndex As Long
lpstrFile As String
nMaxFile As Long
lpstrFileTitle As String
nMaxFileTitle As Long
lpstrInitialDir As String
lpstrTitle As String
flags As Long
nFileOffset As Integer
nFileExtension As Integer
lpstrDefExt As String
lCustData As Long
lpfnHook As Long
lpTemplateName As String
End Type
继续仔细看这个结构体的声明,可以发现成员都是VB的基本数据类型,说明不需要在找其他声明了
第二步:阅读MSDN对于这个API的解释 & 第三步:按照MSDN写代码
这里说的MSDN不是按F1出来那个MSDN,而是MSDN网站。这个是微软的官方开发者网站,里面资料齐全绝对是开发者的天堂
网站有中文版本和英文版本,不过强烈建议大家看英文版本,中文版的翻译质量不好(这就是为什么要求有一定的英文阅读能力)
好吧进入了这个官网之后,在最上面的Bing搜索里面打GetOpenFileName,然后搜索
出来的结果,一般选择xxxx function这种页面,这里选的就是第一个结果GetOpenFileName function
/en-us/library/windows/desktop/ms646927(v=vs.85).aspx
页面打开了,可以看到这个页面分成几大节:
开头:对API的简单介绍
Syntax:语法,也就是API的声明
Parameters:API的参数
Return Value:返回值
Remarks:一些附加的说明
Examples:示例代码,一般都是用C语言写的
Requirements:API对系统的要求等等
See Also:与此相关的API等
Community Additions:其他人对此文章的评论
网页左栏:是整个站点的分类目录
好吧,英文不好的同学要加油了,混国外网站英文是必须要会的
不要觉得一个API能有这么多内容,很多信息都是很有用很关键的,耐心从上往下一节一节读完
开头:这个自己看就是了,对API的介绍和描述,不是很重要的部分(不过有时会有很重要的批注,例如此API不再被微软支持建议用xxx代替之类的)
Syntax:这个就是API的语法,也就是声明啦,C语言的,所以对我们没什么用,可以跳掉不看
如果要根据这个C语言的声明自己写出VB的声明,还是需要一定的C语言数据类型的知识
PS:这里为什么返回值是BOOL,但是我们的声明是Long呢?是不是应该把我们的VB声明改成Boolean?不需要的。BOOL在C里面的定义就是long型(unsigned long?具体忘了,差不多这类东西),占用4字节,所以应该对应VB的Long型。当然,你闲着蛋疼也可以把返回值声明成Single型,同样也是4字节,不过没什么意义
Parameters:API的参数部分啦,整个网页最重要的部分之一
按照这里的解释,填写参数就可以调用API了
好吧这里只有一个参数,网页写的是
lpofn [in, out]
Type: LPOPENFILENAME
这个[in, out]是什么意思呢?in表示这个是个输入参数,这个参数的值会作为输入对API的结果进行影响。out表示这个同时也是个输出参数,API会把部分数据返回到这个参数里面。(除了in和out,有些还会出现optional,表示这是个可选参数)
LPOPENFILENAME说的就是参数的类型,等等,我们的声明不是写的类型是OPENFILENAME吗,怎么这里多了个LP?这个是C语言里指针的意思(long pointer?),意思是当调用API的时候,不是把这个整个OPENFILENAME结构体的数据传过去,而是只把这个结构体的指针传过去。同样的写法还有xxx*,例如OPENFILENAME*
接下来看他对这个参数的描述,大致是这个参数装载着启动这个API的参数,当API返回的时候会把结果放到这个结构体里面
说的基本都是废话,这个结构体有这么多成员,我们还是不知道怎么填,那么就点进去这个OPENFILENAME的链接
点进去之后,发现这个OPENFILENAME文章结构也差不多
Syntax可以跳过,我们已经从API Viewer 里面找到声明了(PS:后面这个#if和#endif中间的是什么东西呢?这个是C的预编译指令,具体可以自己去看,在这里没什么用)
Members,终于在讲解这些成员的意思了,好吧可以开始写代码了,首先在VB里面写
Dim ofn As OPENFILENAME
With ofn
End With
那么接下来就一个一个看成员,看他的解释,是什么意思,应该怎么填
需要注意的一些东西是,不像API的参数,并没有告诉你每个成员是作为输入还是输出的作用,需要自己认真读解释
lStructSize,Type: DWORD
结构体的字节大小,用sizeof(OPENFILENAME)获得
sizeof其实就是C语言里面获得结构体大小的函数,那VB里面我们就用LenB吧(Len也行,不过按照MSDN的说法还是用LenB吧)
(PS:DWORD对应VB的Long)
代码:.lStructSize = LenB(ofn)
hwndOwner,Type: HWND
这个对话框的父窗体的句柄,可以设置成NULL
那我们就做成父窗体是我们的Form1吧
(PS:HWND也是对于VB的Long,NULL则是0)
代码:.hwndOwner = Me.hWnd
hInstance,Type: HINSTANCE
如果要指定对话框的模板,那么这个需要填上模板所在的程序句柄
我们没兴趣用什么模板,windows自带的那个已经够好看了,不理他填个NULL
代码:.hInstance = 0
lpstrFilter,Type: LPCTSTR
文件类型过滤器,格式为 描述文字 \0 *.xxx \0 描述文字 \0 *.xxx \0 。。。。。。。 \0\0
所谓文件类型过滤器,其实就是那个下拉框,例如选择文本文件*.txt就只显示txt文件
C语言中\是转义字符,\0其实就是VB中的chr(0)
那么我们这里做一个简单的吧,用户可以选择文本文件或者是任意文件
(PS:LPCTSTR对应VB的String,详细一点应该这样解读,LP C T STR,LP表示这个是字符串的指针,C表示是常量字符串,就是API执行前后不会被修改,T表示是根据程序设置选择是ANSI还是Unicode编码,STR表示是个字符串)
代码:.lpstrFilter = “文本文件” & Chr(0) & “*.TXT” & Chr(0) & “所有文件” & Chr(0) & “*.*” & Chr(0) & Chr(0)
lpstrCustomFilter,Type: LPTSTR
大概就是如果选的是文本文档txt的过滤器,但是用户强制输了个不是txt后缀,API就会分析这个后缀然后返回到这里
这里有一点必须要读到的是,这个是个缓冲区,API会把数据返回到这里。其实从数据类型也可以看到,这个并不像lpstrFilter一样,这个是LPTSTR而不是LPCTSTR,少了个C意味着这个不是一个常量,可能会被API改变,说明是充当一个缓冲区的作用
我们貌似也对用户选怎么后缀没兴趣,所以按照他的要求,填NULL
但是这个是个String类型,NULL表示一个0指针,VB中String类型的0指针就要填vbNullString
代码:.lpstrCustomFilter = vbNullString
nMaxCustFilter,Type: DWORD
lpstrCustomFilter的缓冲区大小
反正我们对这个没兴趣,按照要求填个0就可以了(实际上,只要lpstrCustomFilter填了NULL,这个填什么都没关系)
代码:.nMaxCustFilter = 0
nFilterIndex,Type: DWORD
Filter的序号,作为输入时是默认过滤器的序号,作为输出时是用户选择了哪个序号
我们就让默认是文本文档的过滤器好了,所以序号是0
代码:.nFilterIndex = 0
lpstrFile,Type: LPTSTR
文件路径,作为输入时是默认选择的文件,作为输出为用户选择的文件路径
可以读到这个是一个输出成员,而且从数据类型LPTSTR也可以看到是非常量的字符串,所以我们需要给他做个缓冲区,让API填数据
按照要求,做缓冲区的话最小大小为256,不过我这里就采用MAX_PATH常量值(表示文件路径的可能的最大长度),260
同时他说,如果要避免成为默认选择的文件,最好给缓冲区全部填\0
代码:.lpstrFile = String(260, 0)
nMaxFile,Type: DWORD
lpstrFile的缓冲区大小
这个不必废话了,lpstrFile我们的缓冲区用的是260,自然就填260了
代码:.nMaxFile = 260
lpstrFileTitle,Type: LPTSTR
返回的文件名,作为输出成员(例如C:\a\b\c\1.txt,文件名就是1.txt)
我们不关心这个文件名,即使关心我们也可以用VB的函数自己获得,不需要,填NULL
代码:.lpstrFileTitle = vbNullString
nMaxFileTitle,Type: DWORD
lpstrFileTitle的缓冲区长度
代码:.nMaxFileTitle = 0
lpstrInitialDir,Type: LPCTSTR
初始文件夹
可以指定一个路径,不过直接填NULL好了,打开对话框有路径记忆功能,会自动设置为上次选择的文件的路径
代码:.lpstrInitialDir = vbNullString
lpstrTitle,Type: LPCTSTR
打开对话框的标题
随便搞个标题上去吧,看个人心情
代码:.lpstrTitle = “选择一个文件来打开”
Flags,Type: DWORD
打开对话框的一些性质
下面列了一堆可选的性质,名字下面是十六进制值,右边是解释
我们大体选择了以下几个我们想要的性质:
OFN_EXPLORER:使用系统自带的对话框模板,win7和vista下看起来会很漂亮
OFN_FILEMUSTEXIST:选择的文件必须存在
OFN_HIDEREADONLY:隐藏只读的多选框
OFN_PATHMUSTEXIST:用户在输入框输入的路径必须存在
这些常数可以在API Viewer 里面查到他们的值,当然一般来说网页都会给出来,复制就是了
使用多个常数的时候,用Or连接
代码:.flags = &H80000 Or &H1000 Or &H4 Or &H800
nFileOffset,Type: WORD
文件名在lpstrFile中的偏移,输出成员
我们对文件名没什么兴趣,而且这个是个输出成员,那我们就不用写代码了
代码:无
nFileExtension,Type: WORD
文件后缀在lpstrFile中的偏移,输出成员
同没兴趣,无代码
代码:无
lpstrDefExt,Type: LPCTSTR
默认的后缀名,当用户没有输入后缀名的时候自动加上去
对此没什么兴趣,按照要求填个NULL
代码:.lpstrDefExt = vbNullString
lpTemplateName,Type: LPCTSTR
打开对话框使用的模板名称
我们使用系统默认的模板,所以这个也没必要,填NULL
代码:.lpTemplateName = vbNullString
好吧终于搞定这些Members了!!
这个网页的其他几节意义都不大,没什么重要信息,我就不说了
好吧回到GetOpenFileName这个网页,我们填完参数了,继续忘下看
Return value:
Type: BOOL
这个是对返回值的解释,也是挺重要的部分
一般返回值会确定API是否执行成功,虽然大部分人调用API都不管这个返回值,但是按照规范应该是判断返回值看是否调用成功
如果用户成功按了确定按钮,那么返回值就是非0,lpstrFile成员包含了用户选择的文件路径;如果点了取消,那么就是0
这样的话,我们把调用和判断返回的代码写出来吧:
If GetOpenFileName(ofn) Then
Else
End If
现在只是调用了GetOpenFileName,但是调用完什么都不做
好吧,既然说了用户选择的文件路径是在lpstrFile里面,那么我们就可以直接拿来用了
但是,有一点必须注意,lpstrFile里面包含了我们分配缓冲区时候多出来的chr(0)
如果不把这些删掉的话,那么出来的路径就有问题了,后面跟着一大堆的chr(0)
声明一个String型变量szPath,用来保存我们处理完之后的文件路径
Dim szPath As String
szPath = Left(ofn.lpstrFile, InStr(ofn.lpstrFile, Chr(0)) - 1)
MsgBox szPath
搞定了用户按确定的代码,现在来做用户点取消的代码,直接一个msgbox显示就好了
MsgBox “没有选择文件”
Remarks:
这部分通常包括很详细的API调用说明,一般有很重要的信息
不过在这里没什么有意义的东西
Requirements:
Minimum supported client/server是这个API对Windows系统版本的最低要求,这里都是Windows 2000
Header就是VC6里面的头文件,这里是Comdlg32.h,如果你有装Visual C++ 6.0的话,找到这个头文件,就可以找到这个API及相关的C语言声明了
Unicode and ANSI names这个是不同编码版本的API名称,这个编码的问题不在本文的讨论范围
好啦经历千辛万苦终于按照步骤做完了,整个窗体的代码就是这个样子(窗体有一个按钮Command1):
Private Declare Function GetOpenFileName Lib “comdlg32.dll” Alias “GetOpenFileNameA” (ByRef pOpenfilename As OPENFILENAME) As Long
Private Type OPENFILENAME
lStructSize As Long
hwndOwner As Long
hInstance As Long
lpstrFilter As String
lpstrCustomFilter As String
nMaxCustFilter As Long
nFilterIndex As Long
lpstrFile As String
nMaxFile As Long
lpstrFileTitle As String
nMaxFileTitle As Long
lpstrInitialDir As String
lpstrTitle As String
flags As Long
nFileOffset As Integer
nFileExtension As Integer
lpstrDefExt As String
lCustData As Long
lpfnHook As Long
lpTemplateName As String
End Type
Private Sub Command1_Click()
Dim ofn As OPENFILENAME
Dim szPath As String
With ofn
.lStructSize = LenB(ofn)
.hwndOwner = Me.hWnd
.hInstance = 0
.lpstrFilter = “文本文件” & Chr(0) & “*.TXT” & Chr(0) & “所有文件” & Chr(0) & “*.*” & Chr(0) & Chr(0)
.lpstrCustomFilter = vbNullString
.nMaxCustFilter = 0
.nFilterIndex = 0
.lpstrFile = String(260, 0)
.nMaxFile = 260
.lpstrFileTitle = vbNullString
.nMaxFileTitle = 0
.lpstrInitialDir = vbNullString
.lpstrTitle = “选择一个文件来打开”
.flags = &H80000 Or &H1000 Or &H4 Or &H800
.lpstrDefExt = vbNullString
.lpTemplateName = vbNullString
End With
If GetOpenFileName(ofn) Then
szPath = Left(ofn.lpstrFile, InStr(ofn.lpstrFile, Chr(0)) - 1)
MsgBox szPath
Else
MsgBox “没有选择文件”
End If
End Sub
运行测试,一切正常!
本文就到这里结束了,希望能帮助到大家的API学习。最后说一句,API不能整天靠网上百度下来的例子代码复制粘贴,自己去MSDN看来写代码,收获更多。
#p##e#
API与Windows
API是系统的基石,是Windows的一砖一瓦。
明确一个概念,软件是运行在系统平台的支持上的,软件的功能其实就是向系统伸请,并由系统完成这些功能的过程。那么软件要做的事情如何传递给系统呢,也就是这些API的作用了,系统定义了这些API函数,做为支持软件执行系统功能的接口。不同的操作系统自然API会是不同的。API是一组作为应用程序呼叫某个功能与服务的函数。程序设计师可依据API函数撰写程序,让操作系统或某个程序激活某个程序以执行特定的功能。
基本上,API是操作系统的框架,通常包含在名为.DLL的动态连接库文件中,可控制Windows各个组件、外观与服务。而这一套事先预定的函数,可与在API下方的操作系统的核心沟通,进而呼叫其它程序或服务,且让程序设计师依据API,架构出各种的Windows应用程序。
API 就是应用程序编程接口。它是能用来操作组件、应用程序或者操作系统的一组函数。典型的情况下,API 由一个或多个提供某种特殊功能的 DLL 组成。(java中有所不同,但大同小异)DLL 是一个文件,其中包含了在 Microsoft Windows 下运行的任何应用程序都可调用的函数。运行时,DLL 中的函数动态地链接到调用它的应用程序中。无论有多少应用程序调用 DLL 中的某个函数,在磁盘上只有一个文件包含该函数,且只在它调入内存时才创建该 DLL。
您听到最多的 API 可能是 Windows API,它包括构成 Windows 操作系统的各种 DLL。每个 Windows 应用程序都直接或间接地与 Windows API 互动。Windows API 保证 Windows 下运行的所有应用程序的行为方式一致。
注意 随着 Windows 操作系统的发展,现已发布了几个版本的 Windows API。Windows 3.1 使用 Win16 API。Microsoft Windows NTindows 95 和 Windows 98 平台使用 Microsoft Win32 API。 除 Windows API 外,其他一些 API 也已发布。例如,邮件应用程序编程接口 (MAPI) 是一组可用于编写电子邮件应用程序的 DLL。
API 传统上是为开发 Windows 应用程序的 C 和 C++ 程序员编写的,但其他的编程语言(包括VBA)也可以调用 DLL 中的函数。因为大部分 DLL 主要是为 C 和 C++ 程序员编写和整理说明的,所以调用 DLL 函数的方法与调用 VBA 函数会有所不同。在使用 API 时必须了解如何给 DLL 函数传递参数。
警告 调用 Windows API 和 其他 DLL 函数可能会给您的应用程序带来不良影响。从自己的代码中直接调用 DLL 函数时,您绕过了 VBA 通常提供的一些安全机制。如果在定义或调用 DLL 函数时出现错误(所有程序员都不可避免),可能会在应用程序中引起应用程序错误(也称为通用性保护错误,或 GPF)。最好的解决办法是在运行代码以前保存该项目,并确保了解 DLL 函数调用的原理。
好的API的特性
简单
首先简单是最重要的。程序员倾向于解决复杂的问题,这使得我们很容易地让这些复杂性影响到编写的用户API。保持简单就需要大量工作,有时还会带来严重的挑战。
我们想要帮助的意愿一定程度上增加了困难。通常,程序员想要提供几种不同的方法来做一些事情。“也许他们想通过构造函数传递这些依赖关系。但是如果他们更喜欢使用setter呢?我们应该让两者都存在。”通向复杂性的道路就是这样良好的意愿铺好的。
即使你认为它可能会有所帮助,也要努力去增加不必要的复杂性。好的api表现出简单性,而且要保持这种简单性需要付出很大的努力。
提供有用的抽象
接下来,考虑抽象的概念。当你成功地从用户的API中隐藏细节只留下要点时,你就提供了抽象。
这个世界充满了抽象的例子。设备驱动程序抽象处理供应商硬件的细节。线程模型提供了一种抽象,用于处理在OS级别上调度执行。操作系统本身为核心计算机硬件的不同提供了一个抽象概念。甚至你的编程语言也会抽象出编写机器代码的细节。
好的代码提供了抽象,API也不例外。你的API应该隐藏它对用户的详细信息,同时使其对用户有用。如果你的用户需要深入代码或执行来理解,你就提供了一个很差的抽象。
可发现的
简单和好的抽象会让你取得不错的成绩。但是,当你写出一个“可发现”的API时,你将走的更远。这与一个新手在使用你的代码时的效率有很大的关系。
我将选用一个非代码示例作有帮助的同类型比较。从用户体验角度想想看,最初的iPhone革命性的是什么。它有一个屏幕和一个按钮。它的应用程序把东西挂在屏幕的一边,让你发现可以通过左右滑动来提高你的使用频率。与之前的设备不同,这款可发现的设备让即使是最不聪明的用户也能快速的进行操作。
让你的API争取做到这一点。要知道,你的用户在拿起手册或打电话询问之前,他们会进行测试和实验。相应的计划和设计,包括文档和示例,以及自我描述访问点会让API具备可发现性。另外使用一个名为GetLastNameFromOrder(CustomerOrder orderToQuery)的方法可以帮助你达到预期目的。
一致和对称
假如你已经偏离了先前的考虑,那么请检查你的API以保持一致性和对称性。一致性相对容易理解。有时候不要称他们为“用户”或“客户”,用相同的方式命名相同的东西,保持一个共同的风格。从而让你的API是可预测的。
对称性是一个稍微有些微妙的考虑。当我谈到对称时,指的是一种以用户期望的方式关闭开放循环的偏好。例如,如果你有一个用于文件访问的API,它允许你调用Open(string文件名),那么你也应该提供一个Close(string文件名)方法。打开和关闭具有相反的含义,因此,提供两种功能都可以作为操作的关注点来创建对称。调用Close方法是“销毁”,而如果没有关闭方法,会造成很大的混乱。
在API中,你可以通过对向用户公开的内容运用批判的眼光来实现这一特性。仔细阅读校对者的方法,检查一致性和对称性,然后根据需要重命名和修改。
遵循最不惊奇的原则
作为最后的考虑,我想给大家介绍一个聪明的“最小惊奇原则”。这表示“一个系统应该以与该组件的用户可能期望的行为一致的方式运行。也就是说,用户不应该对它的行为感到惊讶。”更坦率地说,不要编写API来让你的用户大吃一惊。
我上面关于对称的例子也可以被认为违反了这一原则。但是让我们稍微改变一下,让它更明显地说明这个原则是什么意思。假设你的文件API有一个开放的(字符串文件名)方法,然后它要求你通过调用Open()来关闭文件,而且没有参数。而无论何时你调用Close(),因为某些原因它都会发送一封电子邮件给一个叫Bill Smith的人。如果对这个过程做出反应,你就会得到一个“令人惊讶”的因素。
好的API并没有导致用户抓狂的属性,“但是这没有任何意义!”或者“我怎么知道这一点?!”向用户提供一个与它所宣称的功能无关的API,我想没有什么比这更快捷的方式来失去用户的信任了。
把API看作一种产品
简单、有用、可发现、一致、可预测,所有这些不仅描述了良好的API,还描述了良好的产品。这不是偶然的,当你编写API时,你将创建一个产品。不管你是否真的这样想,不管你是否真的把产品卖了,你手上都有一个别人想要用的产品。
作为开发人员,我们很容易忽视这一点。根据知识的偏差,假设我们的API用户是程序员,他们知道我们所知道的,理解我们所理解的,但我们并不认为他们是最终用户或客户。
要克服这种偏差,换位思考是设计好的API的关键思想。所以当你编写下一个API时,把自己放在客户的角度,想象你想要的是什么。