




已阅读5页,还剩34页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
与其他API协作,7,第七章,API不是单独存在的。光靠它们自己可做不什么有意义的事情;一定要被调用才能完成特定的功能。只有少数的API可以独自运行,无须任何上下文环境。必须了解如何正确地使用第三方API,才不会造成意想不到的后果。本章会就使用、复用、暴露、再导出第三方类这些重要问题展开讨论。,使用第三方API方式通常有两种:一:是把对方提供的API作为一个功能类库来使用,这并不会把第三方的API再暴露给自己的客户;二:是确实存在暴露需求时,需要将第三方API中的接口暴露出来给客户使用。第三方库API再导出。将第三方库类中的API再导出时,一定要认真考虑主API和其他被再导出API的稳定性。主API的稳定性要求非常高,表示需要对再导出的API进行一层包装,而不是直接暴露给客户使用。,7.1谨慎使用第三方API,Moduledbmodule内部的DimcnAsNewSqlConnection(connectionStr)连接数据Functionsearch(ByValsqlstrAsString)AsDataSet搜索函数FunctionUpdated(ByValsqlstrAsString)AsInteger更新函数EndModule,同时又将这个第三方的API暴露给客户。,ModuledbmoduleFunctionSQL_CMD(ByValMSQLstrAsString)AsIntegerReturnUpdated(MSQLstr)EndFunctionFunctionSQL_READ(ByValMSQLstrAsString)AsDataTableDimdsAsNewDataSetds=search(MSQLstr)Returnds.Tables(0)EndFunctionEndModule,要想避免此类问题,只有三种途径:接受这种不兼容性,拒绝这种不兼容性或者使用包装器来防范。第一种方案就是接受这种不兼容性。如果一个API被动再导出以后,一旦出现了不兼容问题,那么最简单的方法就是接受现实,承认自己的主API库也出现了不兼容。一旦第三方类库的新版本出现了不兼容问题,那么也要发布一个新的版本来进行兼容。,三种途径解决方式,API设计和测试(2),第二种方案就是拒绝这种不兼容性。要想防止不兼容性问题,最简单的方法就是保证自己的类库和暴露出去的第三方类库都不存在兼容问题就行了。必须能对第三方类库有足够的影响力,不让其出现讨嫌的不兼容问题.解决方法:修正方法就是不升级到新版本,仍然使用兼容的老版本。仍然存在缺点:就是新版本往往会引入更加有用的功能。但经验表明,继续沿用老的版本库也是一种可行方案。第三种方案就是使用包装模式。对于再导出第三方API而引发的问题,有一种可行的解决方案就是把用到的第三方API进行一次包装,而不是把第三方API直接暴露给客户。,7.2只暴露抽象内容,例如在自己API的某一个方法里暴露了Java.io.File这个类,会使得API的所有用户在调用这个API方法时,可以拿到文件对象,从而可以读取这个文件的内容,同时还可以用向文件中写入自己的内容,通过这个文件结合相对路径,就可以查找到其他相关文件。所以,一旦把一个文件暴露给外部的API方法,就完全对其失去控制了。,7.2只暴露抽象内容(2),对API进行封装,其实意味着在使用一个API的时候,其上下文环境的配置会比较简单,大大地提高其潜在复用度。定义API的环境时,一定要考虑合适的封装方式,要分析常见的用例,也要想到那些不常见的场景,从而在设计时能够在这两者之间取得一个平衡.少就是多.API中暴露的内容越少,那么重用就会更容易.,7.2只暴露抽象内容(2),PublicClassMYdatabasePrivateFunctionGET_TABLE(ByRefSTR1AsString,ByValSTR2AsString)AsStringPublicFunctionNEWS()AsBooleanPublicSubOPEN(ByValpsqlstrAsString)PublicSubOPEN(ByValPTABLEAsString,ByValPEXPAsString)PrivateSubSetDataRow(ByValiAsInt16,ByValvalueAsObject)PrivateSubSet_Value(ByValiAsInteger,ByValvalueAsObject)PublicSubUPDATE_data(ByValpnameAsString,ByValpvalueAsObject)PublicFunctionGET_data(ByValpnameAsString)AsDataRowPrivateSubSetCommandString(ByValiAsInt16)PrivateSubSetCommandSql(ByValiAsInt16,ByValvalueAsString,ByValbsAsString)PublicFunctionSAVE()AsBooleanEndClass,7.3强化API的一致性,在使用一些API的时候,一个可能提供了多种操作方式,当然结果也是相关的.而且这些操作方式是有关联的,.“简单功能类库”就是指那些只提供了实现功能的类库.URLurl=newURL();assertEquals(url.toString(),url.toExternalForm();希望调用URL类的toString和toExternalForm这两个方法能返回相同的的字符串,就需要写一个自动化的单元测试来来进行验证。,7.3强化API的一致性,在Javadoc添加警告信息这种方式,只是把一些问题推给别人。解决此类问题的一种更好的方式就是编写TCK。每一个模块化的类库,都是应该配备一个测试套件,这样开发人员就可以利用这个套件来验证相关具体实现是否正确。,所有的开发人员都是会使用这个套件进行测试工作。有相当一部分API有用户只是去实现API,而忽略了具体内容测试。其实如果使用TCK,这个bug可以在几分钟内定位。TCK是一件辅助开发的利器,只有那些勤勉的程序员才会使用它。,要约束一个方法的行为,最好的方式就是避免这个方法被覆盖。这样做可以把一个类变得像“简单功能类库”一样,不管用户做什么事情,都处于自己的代码的控制之下。,因为只有一个入口,因此能所有用户方法调用都进行检查。这个入口可以把需要的一致性检查、参数机校验等都集中在一处。检查可以根据环境进行调整,也就是说,只在测试环境下进行校验,而在上线系统中就关闭校验,特别是校验会引起比较大的性能问题时,这种处理显得尤为有用。,7.4代理和组合,面向对象语言的核心概念就是继承,应该尽可能地去使用继承。继承为代码复用提供了一种方便的途径。在设计优秀的API时,继承其实用处不大。在设计API时,是否允许外部的继承一直是一个争议的话题。其对外的API并不应该暴露深层次的继承关系。,PublicclassArithmeticaPublicintsumTwo(intone,intsecond)Returnone+second;PublicintsumAll(int.numbers)If(numbers.length=0)Return0;Intsum=numbers0;For(inti=1;inumbers.length;i+)Sum=sumTwo(sum,numbersi);Returnsum;PublicintsumRange(intfrom,intto)Intlen=to-from;If(len0)Len=-len;From=to;Intarray=newintlen+1;For(inti=0;i=len;i+)Arrayi=from+I;ReturnsumAll(array);,10.4代理和组合(2),不安全的程序:经验告诉,这种情况几乎都是是因为允许继而引发的。原因很简单:继承是面向对象技术中支持代码复用的手段,但事实上,它也允许为一个类留下了太多不安全的后门,这些后门可谓远超设计时的规则。大量类引发的问题在于,这些类会定义大量的虚方法,(这些方法需要以后实现),同一个类中的这些虚方法之间是有各种关联联系的。如要读一个API的源代码,那么其设计上一定存在问题。事实上,如果一个类中的方法间有着大量的关联关系,它的设计一定存在问题。要在一个API中定义一个方法是需要三个原因的。,一个API中定义一个方法是需要三个原因,(1)是最重要的,外部可以通过一个方法调用来实现某些功能。(2)利用虚方法另一个原因,是让它可以被具体实现的替换的插件,也就是一个可以在被覆盖的方法。一个子类是可以覆盖父类的虚方法来替换父类的实现。(3)方法调用的第三种方式,就是由子类通过super.methodName这种方法来调用父类的方法,而且这种情况不需要覆盖父类的方法。只允许子类来调用的方法。,覆盖并实现,面向对象语言方面具有更丰富的语义,对于API设计来说其实会凸显得更加模糊。一个API类中看到了一些声明为proteced和abstract的方法,根据上文可以很清楚地知道如何来使用这些方法覆盖并实现。API的用户看到这种设计,很清楚其用法。一个API其实是开发者和用户之间的一种沟通方式,在这个沟通过程中,应该尽可能清楚地说明,而不是把大量的信息给隐藏起来。API中声明成以上三类访问方式越多,那么其API对外的描述会更加清楚。,在设计API时,Java方法访问级别,。,提高API的语义清晰度(2),为了提高API的语义清晰度,同时避免副作用,最好是避免使用那些可能存在问题的方式来声明一个方法。当类中的方法存在多种上语义时,应该知道如何重新编写该类,让其中的方法只有单一而且确定的语义。下面代码中的MixedClass类一样,每个类都是由单一语义的方法组成,那么就可以使用两个类和一个接口来代替原来的抽象类。,提高API的语义清晰度(3),PublicabstractclassMixedClassPrivateintcounter;Privateintsum;ProtectedMixedClass()Super();PublicfinalintapiForClients()Intsubclass=toBeImplementedBySubclass();Sum+=subclass;Returnsum/counter;ProtectedabstractinttoBeImplementedBySubclass();ProtectedfinalvoidtoBeCalledBySubclass()Counter+;其中第一个类用来作为客户端要调用的API,而接口则是留给用户来实现功能,第二个类则用来支持系统回调。,提高API的语义清晰度(5),PublicfinalclassNonMixedPrivateintcounter;Privateintsum;PrivatefinalProviderimpl;PrivateNonMixed(Providerimpl)This.impl=impl;PublicstaticNonMixedcreate(Providerimpl)NonMixedapi=newNonMixed(impl);Callbackcallback=newcallback(api);Impl.initialize(callback);Retuenapi;PublicfinalintapiForClients()Intsubclass=impl.toBeImplementedBySubclass();Sum+=sumclass;Returnsum;counter;,提高API的语义清晰度(6),PublicinterfaceProviderPublicvoidinitialize(Callbackc);PublicinttoBeImplementedBySubclass();PublicstaticfinalclassCallbackNonMixedapi;Callback(NonMixedapi)This.api=api;PublicfinalvoidtoBeCalledBySubclass()api.counter+;对于API的用户来说,其结构却要更加清楚,也更容易理解。,提高API的语义清晰度(7),TestpublicvoiduseWithoutMixedMeanings()ClassAddFiveMixedCounterimplementsNonMixed.ProviderPrivateCallbackcallback;PublicinttoBeImplementedBySubclass()Callback.toBeCalledBySubclass();Return5;Publicvoidiniotialize(Callbackc)Callback=c;NonMixedadd5=NonMixed.create(newAddFiveMixedCounter();assertEquals(“5/1=5”,5,add5.apiForClients();assertEquals(“10/2=5”,5,apiForClients();assertEquals(“15/3=5”,5,apiForClients();。,提高API的语义清晰度(8),代码与原来只使用一个Mixed类相比,确实看起来更加复杂。原因很简单,使用了组合来替换原来的继承。正确地设计API,让每一个API都有明确的功能以及清晰的定义,那么组合可谓是一件利器。它不公清楚而且优雅地为API不同类型的用户分离出相应的接口,而且该解决方案不会使应用变得更加复杂。,7.5避免API的错误,API不仅仅是类、接口加上Javadoc这样简单的组合。所有这些层次之间都需要保持一致性。一个API不能在某个层面说能够完成某种功能,然后一转眼又在另一个层面说,根本不支持这个功能。如果不想在不同层面上都做到一致性,那么不要保证使用类库时所有的内容都要正确输入正确,而且执行的时候,相关的函数都要运行正确。运行的功能多少符合开始人员对数据库操作的预期,造成问题就应该是出在相关内容的定义上。下面的代码就比较合理些。,7.5避免API的错误-6,PublicinterfaceConnectionPublicSavepointsetSavepoint();PublicinterfaceSavepointPublicvoidrollback();新写的版本能够保证接口的声明和运行时结果的这两者之间是匹配的。有UI控件使用了这个接口,它会将配置信息显示给用户,然后允许用户在多种配置间进行切换。这个API是设计成下面这个样子的。,InterfaceProjectConfigurationProviderPublicprojectConfigurationgetConfigurations();PublicprojectConfigurationgetActive();PublicvoidsetActive(projectConfigurationc);InterfaceProjectConfigurationPublicStringgetDisplayName();用户在不了解API内幕的时候也能开发代码,就必须将这种设计和运行的不一致性最小化。,10.6不要滥用JavaBeans那种监听器机制-4,JavaBeans很受欢迎的设计模式,在相应的JVM规范中已经存在了很久。把自己的API也按照相应的规范进行调整,改得像JavaBeans组件一样。有一个用来在编辑器中将特别信息高亮显示的的API,它允许其他模块将各自实现的HighlightsContainerd注册到指定位置。,PublicinterfaceHighlightContainerPublicvoidaddHighli
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- HB-0017-生命科学试剂-MCE
- Glycochenodeoxycholic-acid-3-sulfate-d4-disodium-生命科学试剂-MCE
- 安全培训效果评价方法课件
- 2025恒丰银行成都分行春季校园招聘考前自测高频考点模拟试题附答案详解
- 安全培训效果记录课件
- 财务共享服务协议
- 医疗健康产业科技创新方向
- 视频会议与远程协作综合工具
- 自然中的发现作文(4篇)
- 2025春季中国有研科技集团有限公司校园招聘考前自测高频考点模拟试题有答案详解
- 富贵包形成原因及治疗方法
- 电动起子使用教程
- 10000中国普通人名大全
- 高中数学《组合》公开课优秀课件
- 钢铁冶金学(炼钢学)课件
- 历史虚无主义课件
- 转动设备机械对中技术汇编
- 毕业论文范文3000字(精选十六篇)
- 南京力学小学苏教版六年级上册数学《分数乘分数》公开课课件
- 陶艺制作过程介绍教学课件(共48张)
- 发动机构造第7章 发动机总体结构
评论
0/150
提交评论