第八章设计API时要区分其目标用户群课件_第1页
第八章设计API时要区分其目标用户群课件_第2页
第八章设计API时要区分其目标用户群课件_第3页
第八章设计API时要区分其目标用户群课件_第4页
第八章设计API时要区分其目标用户群课件_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

设计API时要区分其目标用户群8第八章设计API时要区分其目标用户群8第八章

插件、客户端程序的区别:插件:插件是一种遵循一定规范的应用程序接口编写出来的程序。很多软件都有插件,插件有无数种。例如在IE中,安装相关的插件后,WEB浏览器能够直接调用插件程序,用于处理特定类型的文件。客户端程序:客户服务(CustomerService),是指一种以客户为导向的价值观,它整合及管理在预先设定的最优成本——服务组合中的客户界面的所有要素。广义而言,任何能提高客户满意度的内容都属于客户服务的范围之内。

插件、客户端程序的区别:一些程序功能不仅可以直接通过界面进行操作,还可以提供相应的API,以供其他程序来调用,这样第三方程序可以发起通讯,使用相应程序的API指使它完成操作,命令执行完后,控制权返回给调用者。

XMMS的API还提供插件支持,第三方可发商可以通过注册“输出插件”来扩展XMMS的功能。它与前面说的客户端的地位完全不同。第三方的播放场一些程序功能不仅可以直接通过界面进行操作,还SPI组成:是与前面说的客户端的地位完全不同。它没有让XMMS进行任何操作。但它为XMMS增加了很多功能,所以此时的插件不是前文所说的“客户端”。XMMS的这种注册插件来扩展功能的方式是SPI(ServiceProviderInterface)的典型应用。ServiceProviderInterfaceSPI组成:是与前面说的客户端的地位完全不同。它没有让XMM为了说明客户端API和SPI区别,Voidxmms_play();Voidxmms_pause();Voidxmms_add_to_list(char*);使用Java语言来定义API的方式则完全不同。PublicclassXMMS{Publicvoidplay(){doPlay();}Publicvoidpause(){doPause();}PublicvoidaddToPlaylist(Stringfile){doaddToPlaylist(file);}}8.1C和Java语言中如何定义API和SPI(1)为了说明客户端API和SPI区别,8.1C和Java语言C和Java语言中如何定义API和SPI(2)在Java中声明API方式有多种。如说可使用static方法、实例方法、抽象方法、以及final方法,这些都是可以的。但编写一个SPI,情况就不同。如果要使用C语言来为XMMS编写程序一个插件的话,必须要写一个支持回放的函数,代码如下:Voidmy_playbackprints(char*text){Printf(“%s\n”,text);}InterfacePlayback{Publicvoidplayback(byte[]data);}ClassMyCallbackPrintsimplementsXMMS.Playback{Publicvoidplayback(byte[]data){System.out.println(newString(data));}}Xmms.registerPlayback(newMyCallbackPrints());C和Java语言中如何定义API和SPI(2)在Java中声C和Java语言中如何定义API和SPI(3)对于Java程序员,只要所编写的方法不是private、final或者static的,那么就表示该是方法支持调的,而且可以用看成是一个API。对很多程序员,甚至是教师都没有清楚地理解这一点,它也的确不是日常编码的内容。C和Java语言中如何定义API和SPI(3)对于Java程

8.2API演进不同于SPI演进(1)

具体的演进方案则还是取决于具体的接口类型:向API中添加一些内容总是可以的,但要移除一些内容则不行。但对于SPI,移除一些内容可以允许,但不允许添加新的内容。建立契约时,必须清楚地区分哪些是API,提供给外面调用,而哪些是SPI,用来让外部来扩展程序功能。设计时容易犯的最大错误就是将API和SPI混在一个类里。根据SPI的契约,不能添加方法,根据API的契约,也不能减少方法。8.2API演进不同于SPI演进(1)具体的演进方

8.3java.io.Write这个类从JDK1.4到JDK5的演进还需要使用try/catch/finally的方式来进行防御性编码。Try{bufferedWrite.append(what);}catch(UnsupportedOpeartionExceptionex){bufferedWrite.write(what.toString());}这样来调用API的确有点怪。调用一个方法竟然要写四行代码8.3java.io.Write这个类从JDK1.4到java.io.Write的演进(2)假设已有一个优化过Write类,它无须将数据转换成字符串,而是直接处理以提高性能,但用户却可能无法用到这种梦寐以求的优化,PublicclassCountingWriteextendsWrite{Privateintcounter;PublicintgetcharacterCount(){Returncounter;}java.io.Write的演进(2)假设已有一java.io.Write的演进(3)@OverridePublicvoidwrite(char[]cbuf,intoff,intlen)throwsIoException{Counter+=len;}@OverridePublicWriteappend(CharSepuencecsq)throwsIoException{Counter+=csq.length();Returnthis;}。java.io.Write的演进(3)@Override

PrivatestaticfinalclassCDSequenceimplementsCharSequence{Privatefinalintstart;Privatefinalintend;PublicCDSequence(){This(0,647*1024*1024);}PrivateCDSequence(intstart,intend){

This.start=start;This.end=end;}Publicintlength(){Returnend-start;}}CountingWriterwriter=newCountingWriter();CDSequencecdImage=newCDSequence();BufferedWriterbufferedWriter=newBufferedWriter(writer);bufferedWriter.append(cdImage);assertEquals(“Correctnumberofwritesdelegated”,cdImage.length(),writer.getCharacterCount());Privatestaticfinalclass从JDK1.4到JDK5的演进(4)这个通过覆盖来优化性能的方法却不会被调用,效率仍然没有提高。If(shouldBufferAsTheSequenceIsNotTooBig(csq)){Write(csq.toString());}else{Flush();Out.append(csq);}Returnthis;从JDK1.4到JDK5的演进(4)这个通过覆盖来优化性能的从JDK1.4到JDK5的演进(5)首先计算一下字符的数量,如果数量比较小,性能影响也比较小,就使用老的方式处理,否则就先写入当前数据后,再写入大数据。然而,还远远没有结束,还有一个潜在的问题需要解决。

PublicclassCryptoWriterextendsBufferedWriter{PublicCryptoWriter(Writerout){Super(out);}@OverridePublicvoidwrite(char[]buf,intoff,intlen)throwsIoException{Char[]arr=newchar[len];For(inti=0;i<len;i++){Arr[i]=encryptChar(buf[off+i]);}Super.write(arr,0,len);}从JDK1.4到JDK5的演进(5)首先计算一下从JDK1.4到JDK5的演进(6)@OverridePublicvoidwrite(intc)throwsIoException{Super.write(encryptChar©);}@overridePublicvoidwrite(Stringstr,intoff,intlen)throwsIoException{StringBuffersb=newStringBuffer();For(inti+0;i<len;I++){Sb.append(encryptChar(str.charAt(off+i)));}Super.write(sb.toString(),0,len);}PrivatecharencryptChar(intc){If(c==‘Z’){Return‘A’;}If(c==’z’){Return‘a’;}Return(char)(c+1);}}。从JDK1.4到JDK5的演进(6)@Override从JDK1.4到JDK5的演进(7)事情变得越来越复杂了!为了处理含有大量字符串的对象等目的,最好是直接将数据写入相应的Writer对象。

BooleanisOverriden=false;Try{isOverriden=(getClas().getMethod(“write”,String.class).getDeclaringClass()!=Writer.class)||

(getClass().getMethod(“write”,integer.TYPE).getDeclaringClass!=BufferedWriter.class)||(getClass().getMethod(“write”,String.class,Integer.TYPE,Integer.TYPE).getDeclaringClass()!=BufferedWriter.class);}catch(Exceptionex){ThrowsnewIoException(ex);}If(isOverriden||shouldBufferAsTheSequenceIsNotTooBig(csq)){

Write(csq.toString());}else{Flush();Out.append(csq);}Returnthis;}从JDK1.4到JDK5的演进(7)事情变得越来越复杂了!为反射技术

第三个版本才是最终的解决方案。它使用了反射技术,所以看起来复杂一点,但却是一个非常有效的解决方案。反射技术让这段代码看起来不如原来那么漂亮了,但至少它可以正常运行,结果也是正确的。让一个类可以被动继承,其实就意味着把它当作一个SPI,因为其子类可以提共新技术部的功能,或者说新的服务,但对于代理来说,它更多是让其它的代码来进行调用它的功能,属于功能API,两者是不一样。不能像表面看起来那么简单、顺畅了。反射技术第三个版本才是最终的解决方案。它使用了反射技术如何避免继承(1)PublicfinalclassWriter{PrivatefinalImplimpl;PrivateWriter(Impl,impl){This.impl=impl;}Publicfinalvoidwrite(intc)throwsIoException{Char[]arr={(char)c};Impl.write(arr,0,1);}Publicfinalvoidwrite(charcbuf[])thrpwsIoException{Impl.write(cbuf,0,cbuf.length);}Publicfinalvoidwrite(charcbuf[],intoff,intlen)ThrowsIoException{Impl.write(cbuf,off,len);}Publicfinalvoidwrite(Stringstr)throwsIoException{Impl.write(str,0,str.length());}如何避免继承(1)PublicfinalclassWr如何避免继承(2)Publicfinalvoidwrite(Stringstr,intoff,intlen)ThrowsIoException{Impl.write(str,off,len);}Publicfinalvoidflush()throwsIoException{Impl.flush();}Publicfinalvoidclose()throwsIoException{Impl.close();}如何避免继承(2)PublicfinalvoidwriSPI的提供者类(1)现在写一个SPI的提供者类,这个类中全部都是工厂方法,用来提供Impl接口的具体实现,基本上就是下面这个样子。PublicstaticWritercreat(Implimpl){ReturnnewWriter(impl);}PublicstaticWritercreat(finaljava.io.Writerw){ReturnnewWriter(newImpl(){PublicvoidWrite(String,str,intoff,intlen)ThrowsIoException{w.Write(str,off,len);}SPI的提供者类(1)现在写一个SPI的提供者类,这个类中全SPI的提供者类(2)Publicvoidwrite(char[]arr,intoff,intlen)ThrowsIoException{w.write(arr,off,len);}Publicvoidclose()throwsIoExcepton{w.close();}Publicvoidflush()throwsIoException{w.flush();}}PublicstaticWritercreatBuffered(finalWriterout){Returncreate(newSimpleBuffer(out));}PublicstaticinterfaceImpl{Publicvoidclose()throwsIoException;Publicvoidflush()throwsIoException;Publicvoidwrite(Strings,intoff,intlen)throwsIoException;Publicvoidwrite(char[]a,intoff,intlen)throwsIoException;}}SPI的提供者类(2)Publicvoidwrite(cSPI的提供者类(3)PublicfinalclassWriterimplementsAppendable{PrivatefinalImplimpl;PrivatefinalImplSeqseq;PrivateWriter((Implimpl,ImplSeqseq){This.impl=impl;Thisseq=seq;}Publicfinalvoidwrite(intc)throwsIException{If(impl!=null){Char[]arr={(char)c};Impl.write(arr,0,1)

}else{Seq.write(newCharSeq(c));}}Publicfinalvoidwrite(charcbuf[])throwsIoException{If(impl!=null){Impl.write(cbuf,0,cbuf.length);}else{Seq.write(newCharSeq(cbuf,0,cbuf.length));}}SPI的提供者类(3)PublicfinalclassSPI的提供者类(4)Publicfinalvoidwrite(charcbuf[],intoff,intlen)ThrowsIoException{If(impl!=null){Impl.write(cbuf,off,len);}else{Seq.write(newCharSeq(cbuf,off,len));}}Publicfinalvoidwrite(Stringstr)throwsIoException{If(impl!=null){Impl.write(str,0,str.length));}else{Seq.write(str);}}Publicfinalvoidwrite(Stringstr,intoff,intlen)ThrowsIoException{If(impl!=null){Impl.write(str,off,len);}else{Seq.write(str.subSequence(off,off+len));}}SPI的提供者类(4)PublicfinalvoidwSPI的提供者类(5)Publicfinalvoidflush()throwsIoException{If(impl!=null){Impl.flush();}else{Seq.flush();}}Publicfinalvoidclose()throwsIoException{If(impl!=null){Impl.close();}else{Seq.flush();}}SPI的提供者类(5)PublicfinalvoidfSPI的提供者类(6)设计给客户使用API,最好用final类;而设计SPI的时候,则最好用接口,然后通过一个工厂模式将它们结合在一起。借助“工厂设计模式”尽可能是对客户“隐藏了”相应的复杂度,在API功能时,用户则只看到final类Writer,对于要扩展API功能的人,则只需要看到两个要实现的接口Impl和ImplSeq,所以不管是使用还是扩展这个API,复杂度都不高。虽然根据这个方案写出第一个版本API时,也许工作量会多一些,但是将客户用到功能性API和SPI分离出来,大大降低了演进难度,避免出现将代理与继承混合时出现的那种问题。SPI的提供者类(6)设计给客户使用API,最好8.4合理分解API(1)可以把API分为两类,一类是供他人调用来完成某些功能,还有一类是他人来扩展API功能的,也就是前面说的SPI。任何API都会显示出一定的内聚性:表现为把相关的内容放得比较近,比如说把有关联的内容放在一个类里,或者放在同一个包中,可能就是放在同一个模块里了。面向对象语言都有内聚性的倾向。8.4合理分解API(1)可以把API分为两类,一类是供合理分解API(2)期望来组织你的API,方便他们快速找到自己的内容。。把有关联的方法放置在同一个类中;。对于一些无关系的方法,决不能因为一时无法找到更合适的位置来放置,就随便放入与它们无关的地方;。把有关联的类放置在同一个包中;。把一些只有特殊场景下才用得到的类转移到其他地方。好好地遵守,就可以用有效地提高API的内聚性。合理分解API(2)期望来组织你的API合理分解API(3)我们在文档里使用大幅的文字来敬告用户要根据自己的要求去使用正确的类,并不是通过一些强制转换来滥用API。把API和SPI进行分离并不能解决所有的问题。如果不开发人员不能对API和SPI不同点达成共识,新的问题就会出现。用来让他人调用以完成某些功能的内容,可以用称作API,而SPI则是由他人来具体实现的内容。合理分解API(3)我们在文档里使用大幅的文字来敬告用户要合理分解API(4)一直很强调API和SPI之间的一个不同点:API包中的类应该是自包含的,不会引入任何SPI包中的内容。这样就在API和SPI间划上了一条泾渭分明的边界。不管是监听器还是别的回调接口,只要与API有关,都是要放置在相同的位置。合理分解API(4)一直很强调API和SPI之间的一个不同合理分解API(5)NetBeans项目把API分成四类:。核心类型的API这类API的用户往往只关心类库提供了哪些功能,他们需要使用这个类库来执行哪些关键操作,而这个类库的使用又离不开这类API。。支持类型的API主要是大量的实用方法,可以让用户更容易地使用类库。。核心类型的SPI这是提供给另外一种用户群体使用的接口,这类用户希望通过这些接口来扩展类库的功能。。支持类型的SPI有时候为了扩展功能去实现某个接口,还是一件比较复杂的事情。合理分解API(5)NetBeans项目把API分成四类:设计API时要区分其目标用户群8第八章设计API时要区分其目标用户群8第八章

插件、客户端程序的区别:插件:插件是一种遵循一定规范的应用程序接口编写出来的程序。很多软件都有插件,插件有无数种。例如在IE中,安装相关的插件后,WEB浏览器能够直接调用插件程序,用于处理特定类型的文件。客户端程序:客户服务(CustomerService),是指一种以客户为导向的价值观,它整合及管理在预先设定的最优成本——服务组合中的客户界面的所有要素。广义而言,任何能提高客户满意度的内容都属于客户服务的范围之内。

插件、客户端程序的区别:一些程序功能不仅可以直接通过界面进行操作,还可以提供相应的API,以供其他程序来调用,这样第三方程序可以发起通讯,使用相应程序的API指使它完成操作,命令执行完后,控制权返回给调用者。

XMMS的API还提供插件支持,第三方可发商可以通过注册“输出插件”来扩展XMMS的功能。它与前面说的客户端的地位完全不同。第三方的播放场一些程序功能不仅可以直接通过界面进行操作,还SPI组成:是与前面说的客户端的地位完全不同。它没有让XMMS进行任何操作。但它为XMMS增加了很多功能,所以此时的插件不是前文所说的“客户端”。XMMS的这种注册插件来扩展功能的方式是SPI(ServiceProviderInterface)的典型应用。ServiceProviderInterfaceSPI组成:是与前面说的客户端的地位完全不同。它没有让XMM为了说明客户端API和SPI区别,Voidxmms_play();Voidxmms_pause();Voidxmms_add_to_list(char*);使用Java语言来定义API的方式则完全不同。PublicclassXMMS{Publicvoidplay(){doPlay();}Publicvoidpause(){doPause();}PublicvoidaddToPlaylist(Stringfile){doaddToPlaylist(file);}}8.1C和Java语言中如何定义API和SPI(1)为了说明客户端API和SPI区别,8.1C和Java语言C和Java语言中如何定义API和SPI(2)在Java中声明API方式有多种。如说可使用static方法、实例方法、抽象方法、以及final方法,这些都是可以的。但编写一个SPI,情况就不同。如果要使用C语言来为XMMS编写程序一个插件的话,必须要写一个支持回放的函数,代码如下:Voidmy_playbackprints(char*text){Printf(“%s\n”,text);}InterfacePlayback{Publicvoidplayback(byte[]data);}ClassMyCallbackPrintsimplementsXMMS.Playback{Publicvoidplayback(byte[]data){System.out.println(newString(data));}}Xmms.registerPlayback(newMyCallbackPrints());C和Java语言中如何定义API和SPI(2)在Java中声C和Java语言中如何定义API和SPI(3)对于Java程序员,只要所编写的方法不是private、final或者static的,那么就表示该是方法支持调的,而且可以用看成是一个API。对很多程序员,甚至是教师都没有清楚地理解这一点,它也的确不是日常编码的内容。C和Java语言中如何定义API和SPI(3)对于Java程

8.2API演进不同于SPI演进(1)

具体的演进方案则还是取决于具体的接口类型:向API中添加一些内容总是可以的,但要移除一些内容则不行。但对于SPI,移除一些内容可以允许,但不允许添加新的内容。建立契约时,必须清楚地区分哪些是API,提供给外面调用,而哪些是SPI,用来让外部来扩展程序功能。设计时容易犯的最大错误就是将API和SPI混在一个类里。根据SPI的契约,不能添加方法,根据API的契约,也不能减少方法。8.2API演进不同于SPI演进(1)具体的演进方

8.3java.io.Write这个类从JDK1.4到JDK5的演进还需要使用try/catch/finally的方式来进行防御性编码。Try{bufferedWrite.append(what);}catch(UnsupportedOpeartionExceptionex){bufferedWrite.write(what.toString());}这样来调用API的确有点怪。调用一个方法竟然要写四行代码8.3java.io.Write这个类从JDK1.4到java.io.Write的演进(2)假设已有一个优化过Write类,它无须将数据转换成字符串,而是直接处理以提高性能,但用户却可能无法用到这种梦寐以求的优化,PublicclassCountingWriteextendsWrite{Privateintcounter;PublicintgetcharacterCount(){Returncounter;}java.io.Write的演进(2)假设已有一java.io.Write的演进(3)@OverridePublicvoidwrite(char[]cbuf,intoff,intlen)throwsIoException{Counter+=len;}@OverridePublicWriteappend(CharSepuencecsq)throwsIoException{Counter+=csq.length();Returnthis;}。java.io.Write的演进(3)@Override

PrivatestaticfinalclassCDSequenceimplementsCharSequence{Privatefinalintstart;Privatefinalintend;PublicCDSequence(){This(0,647*1024*1024);}PrivateCDSequence(intstart,intend){

This.start=start;This.end=end;}Publicintlength(){Returnend-start;}}CountingWriterwriter=newCountingWriter();CDSequencecdImage=newCDSequence();BufferedWriterbufferedWriter=newBufferedWriter(writer);bufferedWriter.append(cdImage);assertEquals(“Correctnumberofwritesdelegated”,cdImage.length(),writer.getCharacterCount());Privatestaticfinalclass从JDK1.4到JDK5的演进(4)这个通过覆盖来优化性能的方法却不会被调用,效率仍然没有提高。If(shouldBufferAsTheSequenceIsNotTooBig(csq)){Write(csq.toString());}else{Flush();Out.append(csq);}Returnthis;从JDK1.4到JDK5的演进(4)这个通过覆盖来优化性能的从JDK1.4到JDK5的演进(5)首先计算一下字符的数量,如果数量比较小,性能影响也比较小,就使用老的方式处理,否则就先写入当前数据后,再写入大数据。然而,还远远没有结束,还有一个潜在的问题需要解决。

PublicclassCryptoWriterextendsBufferedWriter{PublicCryptoWriter(Writerout){Super(out);}@OverridePublicvoidwrite(char[]buf,intoff,intlen)throwsIoException{Char[]arr=newchar[len];For(inti=0;i<len;i++){Arr[i]=encryptChar(buf[off+i]);}Super.write(arr,0,len);}从JDK1.4到JDK5的演进(5)首先计算一下从JDK1.4到JDK5的演进(6)@OverridePublicvoidwrite(intc)throwsIoException{Super.write(encryptChar©);}@overridePublicvoidwrite(Stringstr,intoff,intlen)throwsIoException{StringBuffersb=newStringBuffer();For(inti+0;i<len;I++){Sb.append(encryptChar(str.charAt(off+i)));}Super.write(sb.toString(),0,len);}PrivatecharencryptChar(intc){If(c==‘Z’){Return‘A’;}If(c==’z’){Return‘a’;}Return(char)(c+1);}}。从JDK1.4到JDK5的演进(6)@Override从JDK1.4到JDK5的演进(7)事情变得越来越复杂了!为了处理含有大量字符串的对象等目的,最好是直接将数据写入相应的Writer对象。

BooleanisOverriden=false;Try{isOverriden=(getClas().getMethod(“write”,String.class).getDeclaringClass()!=Writer.class)||

(getClass().getMethod(“write”,integer.TYPE).getDeclaringClass!=BufferedWriter.class)||(getClass().getMethod(“write”,String.class,Integer.TYPE,Integer.TYPE).getDeclaringClass()!=BufferedWriter.class);}catch(Exceptionex){ThrowsnewIoException(ex);}If(isOverriden||shouldBufferAsTheSequenceIsNotTooBig(csq)){

Write(csq.toString());}else{Flush();Out.append(csq);}Returnthis;}从JDK1.4到JDK5的演进(7)事情变得越来越复杂了!为反射技术

第三个版本才是最终的解决方案。它使用了反射技术,所以看起来复杂一点,但却是一个非常有效的解决方案。反射技术让这段代码看起来不如原来那么漂亮了,但至少它可以正常运行,结果也是正确的。让一个类可以被动继承,其实就意味着把它当作一个SPI,因为其子类可以提共新技术部的功能,或者说新的服务,但对于代理来说,它更多是让其它的代码来进行调用它的功能,属于功能API,两者是不一样。不能像表面看起来那么简单、顺畅了。反射技术第三个版本才是最终的解决方案。它使用了反射技术如何避免继承(1)PublicfinalclassWriter{PrivatefinalImplimpl;PrivateWriter(Impl,impl){This.impl=impl;}Publicfinalvoidwrite(intc)throwsIoException{Char[]arr={(char)c};Impl.write(arr,0,1);}Publicfinalvoidwrite(charcbuf[])thrpwsIoException{Impl.write(cbuf,0,cbuf.length);}Publicfinalvoidwrite(charcbuf[],intoff,intlen)ThrowsIoException{Impl.write(cbuf,off,len);}Publicfinalvoidwrite(Stringstr)throwsIoException{Impl.write(str,0,str.length());}如何避免继承(1)PublicfinalclassWr如何避免继承(2)Publicfinalvoidwrite(Stringstr,intoff,intlen)ThrowsIoException{Impl.write(str,off,len);}Publicfinalvoidflush()throwsIoException{Impl.flush();}Publicfinalvoidclose()throwsIoException{Impl.close();}如何避免继承(2)PublicfinalvoidwriSPI的提供者类(1)现在写一个SPI的提供者类,这个类中全部都是工厂方法,用来提供Impl接口的具体实现,基本上就是下面这个样子。PublicstaticWritercreat(Implimpl){ReturnnewWriter(impl);}PublicstaticWritercreat(finaljava.io.Writerw){ReturnnewWriter(newImpl(){PublicvoidWrite(String,str,intoff,intlen)ThrowsIoException{w.Write(str,off,len);}SPI的提供者类(1)现在写一个SPI的提供者类,这个类中全SPI的提供者类(2)Publicvoidwrite(char[]arr,intoff,intlen)ThrowsIoException{w.write(arr,off,len);}Publicvoidclose()throwsIoExcepton{w.close();}Publicvoidflush()throwsIoException{w.flush();}}PublicstaticWritercreatBuffered(finalWriterout){Returncreate(newSimpleBuffer(out));}PublicstaticinterfaceImpl{Publicvoidclose()throwsIoException;Publicvoidflush()throwsIoException;Publicvoidwrite(Strings,intoff,intlen)throwsIoException;Publicvoidwrite(char[]a,intoff,intlen)throwsIoException;}}SPI的提供者类(2)Publicvoidwrite(cSPI的提供者类(3)PublicfinalclassWriterimplementsAppendable{PrivatefinalImplimpl;PrivatefinalImplSeqseq;PrivateWriter((Implimpl,ImplSeqseq){This.impl=impl;Thisseq=seq;}Publicfinalvoidwrite(intc)throwsIException{If(impl!=null){Char[]arr={(char)c};Impl.write(arr,0,1)

}else{Seq.write(newCharSeq(c));}}Publicfinalvoidwrite(charcbuf[])throwsIoException{If(impl!=null){Impl.write(cbuf,0,cbuf.length);}else{Seq.write(newCharSeq(cbuf,0,cbuf.length));}}SPI的提供者类(3)PublicfinalclassSPI的提供者类(4)Publicfinalvoidwrite(charcbuf[],intoff,intlen)ThrowsIoException{If(impl!=null){Impl.write(cbuf,off,len);}else{Seq.write(newCharSeq(cbuf,off,len));}}Publicfinalvoidwrite(String

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论