《《与其他api协作》ppt课件》由会员分享,可在线阅读,更多相关《《与其他api协作》ppt课件(39页珍藏版)》请在金锄头文库上搜索。
1、与其他API协作,7,第七 章,API不是单独存在的。光靠它们自己可做不什么有意义的事情;一定要被调用才能完成特定的功能。 只有少数的API可以独自运行,无须任何上下文环境。必须了解如何正确地使用第三方API,才不会造成意想不到的后果。 本章会就使用、复用、暴露、再导出第三方类这些重要问题展开讨论。,使用第三方API方式通常有两种: 一:是把对方提供的API作为一个功能类库来使用,这并不会把第三方的API再暴露给自己的客户; 二:是确实存在暴露需求时,需要将第三方API中的接口暴露出来给客户使用。 第三方库API再导出。将第三方库类中的API再导出时,一定要认真考虑主API和其他被再导出API
2、的稳定性。主API的稳定性要求非常高,表示需要对再导出的API进行一层包装,而不是直接暴露给客户使用。,7.1 谨慎使用第三方API,Module dbmodule 内部的 Dim cn As New SqlConnection(connectionStr) 连接数据 Function search(ByVal sqlstr As String) As DataSet 搜索函数 Function Updated(ByVal sqlstr As String) As Integer 更新函数 End Module,同时又将这个第三方的API暴露给客户。,Module dbmodule Funct
3、ion SQL_CMD(ByVal MSQLstr As String) As Integer Return Updated(MSQLstr) End Function Function SQL_READ(ByVal MSQLstr As String) As DataTable Dim ds As New DataSet ds = search(MSQLstr) Return ds.Tables(0) End Function End Module,要想避免此类问题,只有三种途径:接受这种不兼容性,拒绝这种不兼容性或者使用包装器来防范。 第一种方案就是接受这种不兼容性。如果一个API被动再导
4、出以后,一旦出现了不兼容问题,那么最简单的方法就是接受现实,承认自己的主API库也出现了不兼容。一旦第三方类库的新版本出现了不兼容问题,那么也要发布一个新的版本来进行兼容。,三种途径解决方式,API设计和测试(2),第二种方案就是拒绝这种不兼容性。要想防止不兼容性问题,最简单的方法就是保证自己的类库和暴露出去的第三方类库都不存在兼容问题就行了。必须能对第三方类库有足够的影响力,不让其出现讨嫌的不兼容问题. 解决方法:修正方法就是不升级到新版本,仍然使用兼容的老版本。仍然存在缺点:就是新版本往往会引入更加有用的功能。 但经验表明,继续沿用老的版本库也是一种可行方案。 第三种方案就是使用包装模式。
5、对于再导出第三方API而引发的问题,有一种可行的解决方案就是把用到的第三方API进行一次包装,而不是把第三方API直接暴露给客户。,7.2 只暴露抽象内容,例如在自己API的某一个方法里暴露了Java.io.File这个类,会使得API的所有用户在调用这个API方法时,可以拿到文件对象,从而可以读取这个文件的内容,同时还可以用向文件中写入自己的内容,通过这个文件结合相对路径,就可以查找到其他相关文件。 所以,一旦把一个文件暴露给外部的API方法,就完全对其失去控制了。,7.2 只暴露抽象内容(2),对API进行封装,其实意味着在使用一个API的时候,其上下文环境的配置会比较简单,大大地提高其潜
6、在复用度。 定义API的环境时,一定要考虑合适的封装方式,要分析常见的用例,也要想到那些不常见的场景,从而在设计时能够在这两者之间取得一个平衡. 少就是多.API中暴露的内容越少,那么重用就会更容易.,7.2 只暴露抽象内容(2),Public Class MYdatabase Private Function GET_TABLE(ByRef STR1 As String, ByVal STR2 As String) As String Public Function NEWS() As Boolean Public Sub OPEN(ByVal psqlstr As String) Publ
7、ic Sub OPEN(ByVal PTABLE As String, ByVal PEXP As String) Private Sub SetDataRow(ByVal i As Int16, ByVal value As Object) Private Sub Set_Value(ByVal i As Integer, ByVal value As Object) Public Sub UPDATE_data(ByVal pname As String, ByVal pvalue As Object) Public Function GET_data(ByVal pname As Str
8、ing) As DataRow Private Sub SetCommandString(ByVal i As Int16) Private Sub SetCommandSql(ByVal i As Int16, ByVal value As String, ByVal bs As String) Public Function SAVE() As Boolean End Class,7.3 强化API的一致性,在使用一些API的时候,一个可能提供了多种操作方式,当然结果也是相关的.而且这些操作方式是有关联的,. “简单功能类库”就是指那些只提供了实现功能的类库. URL url=new UR
9、L(http:/www.apidesign.org); assertEquals(url.toString(),url.toExternalForm(); 希望调用URL类的toString和toExternalForm这两个方法能返回相同的的字符串,就需要写一个自动化的单元测试来来进行验证。,7.3 强化API的一致性,在Javadoc添加警告信息这种方式,只是把一些问题推给别人。解决此类问题的一种更好的方式就是编写TCK。每一个模块化的类库,都是应该配备一个测试套件,这样开发人员就可以利用这个套件来验证相关具体实现是否正确。,所有的开发人员都是会使用这个套件进行测试工作。有相当一部分API
10、有用户只是去实现API,而忽略了具体内容测试。其实如果使用TCK,这个bug可以在几分钟内定位。TCK是一件辅助开发的利器,只有那些勤勉的程序员才会使用它。,要约束一个方法的行为,最好的方式就是避免这个方法被覆盖。这样做可以把一个类变得像“简单功能类库”一样,不管用户做什么事情,都处于自己的代码的控制之下。,因为只有一个入口,因此能所有用户方法调用都进行检查。这个入口可以把需要的一致性检查、参数机校验等都集中在一处。检查可以根据环境进行调整,也就是说,只在测试环境下进行校验,而在上线系统中就关闭校验,特别是校验会引起比较大的性能问题时,这种处理显得尤为有用。,7.4 代理和组合,面向对象语言的
11、核心概念就是继承,应该尽可能地去使用继承。继承为代码复用提供了一种方便的途径。 在设计优秀的API时,继承其实用处不大。在设计API时,是否允许外部的继承一直是一个争议的话题。其对外的API并不应该暴露深层次的继承关系。,Public class Arithmetica Public int sumTwo(int one,int second) Return one+second; Public int sumAll(int.numbers) If (numbers.length =0) Return 0; Int sum=numbers0; For (inti=1;inumbers.leng
12、th;i+) Sum=sumTwo(sum,numbersi); Return sum; Public int sumRange(int from,int to) Int len=to-from; If (len0) Len=-len; From=to; Int array=new intlen+1; For (int i=0;i=len;i+) Arrayi=from +I; Return sumAll(array); ,10.4 代理和组合(2),不安全的程序:经验告诉,这种情况几乎都是是因为允许继而引发的。 原因很简单:继承是面向对象技术中支持代码复用的手段,但事实上,它也允许为一个类留
13、下了太多不安全的后门,这些后门可谓远超设计时的规则。 大量类引发的问题在于,这些类会定义大量的虚方法,(这些方法需要以后实现),同一个类中的这些虚方法之间是有各种关联联系的。 如要读一个API的源代码,那么其设计上一定存在问题。事实上,如果一个类中的方法间有着大量的关联关系,它的设计一定存在问题。 要在一个API中定义一个方法是需要三个原因的。,一个API中定义一个方法是需要三个原因,(1)是最重要的,外部可以通过一个方法调用来实现某些功能。 (2)利用虚方法另一个原因,是让它可以被具体实现的替换的插件,也就是一个可以在被覆盖的方法。一个子类是可以覆盖父类的虚方法来替换父类的实现。 (3)方法
14、调用的第三种方式,就是由子类通过super.methodName这种方法来调用父类的方法,而且这种情况不需要覆盖父类的方法。只允许子类来调用的方法。,覆盖并实现,面向对象语言方面具有更丰富的语义,对于API设计来说其实会凸显得更加模糊。一个API类中看到了一些声明为proteced和abstract的方法,根据上文可以很清楚地知道如何来使用这些方法覆盖并实现。API的用户看到这种设计,很清楚其用法。一个API其实是开发者和用户之间的一种沟通方式,在这个沟通过程中,应该尽可能清楚地说明,而不是把大量的信息给隐藏起来。API中声明成以上三类访问方式越多,那么其API对外的描述会更加清楚。,在设计A
15、PI时,Java方法访问级别,。,提高API的语义清晰度(2),为了提高API的语义清晰度,同时避免副作用,最好是避免使用那些可能存在问题的方式来声明一个方法。 当类中的方法存在多种上语义时,应该知道如何重新编写该类,让其中的方法只有单一而且确定的语义。下面代码中的MixedClass类一样,每个类都是由单一语义的方法组成,那么就可以使用两个类和一个接口来代替原来的抽象类。,提高API的语义清晰度(3),Public abstract class MixedClass Private int counter; Private int sum; Protected MixedClass () S
16、uper(); Public final int apiForClients () Int subclass=toBeImplementedBySubclass(); Sum+=subclass; Return sum/counter; Protected abstract int toBeImplementedBySubclass(); Protected final void toBeCalledBySubclass() Counter+; 其中第一个类用来作为客户端要调用的API,而接口则是留给用户来实现功能,第二个类则用来支持系统回调。,提高API的语义清晰度(5),Public final class NonMixed Private int counter; Private int