23
API 设设设设设设 设设 IO API

API 设计实例分析

  • Upload
    malaya

  • View
    116

  • Download
    0

Embed Size (px)

DESCRIPTION

API 设计实例分析. 通用 IO API. 目录. IO API 设计实例分析 IO 要解决 的功能 典型场景,划分 功能 接口 整理 标准使用方式(客户) 拦截 [ 传输 ] 过程 IO API 实现说明 成本收益分析. IO API 设计实例 分析. IO 要 解决的 功能. 多数据类型 String 、 Byte[] 、领域对象 多数据来源 文件、 SPI Provider 异常处理、善后虚处理(如资源释放) IO 类型转换 附加分析: IO 计数等等. 典型场景,划分功能. - PowerPoint PPT Presentation

Citation preview

Page 1: API 设计实例分析

API 设计实例分析

通用 IO API

Page 2: API 设计实例分析

2

目录 IO API 设计实例分析

1. IO 要解决的功能2. 典型场景,划分功能3. 接口整理4. 标准使用方式(客户)5. 拦截 [ 传输 ] 过程

IO API 实现说明 成本收益分析

Page 3: API 设计实例分析

3

IO API 设计实例分析

Page 4: API 设计实例分析

4

IO 要解决的功能 多数据类型

String 、 Byte[] 、领域对象 多数据来源

文件、 SPI Provider 异常处理、善后虚处理(如资源释放) IO 类型转换 附加分析: IO 计数等等

Page 5: API 设计实例分析

5

典型场景,划分功能1: File source = new File( getClass().getResource( "/iotest.txt" ).getFile() );1: File destination = File.createTempFile( "test", ".txt" );1: destination.deleteOnExit();2: BufferedReader reader = new BufferedReader(new FileReader(source));3: long count = 0;

2: try {4: BufferedWriter writer = new BufferedWriter(new FileWriter(destination));4: try {2: String line = null;2: while ((line = reader.readLine()) != null) {3: count++;4: writer.append( line ).append( '\n' );2: }

4: writer.close();4: } catch (IOException e) {4: writer.close();4: destination.delete();4: }2: } finally {2: reader.close();2: }3: System.out.println(count)

Page 6: API 设计实例分析

6

接口整理 (1)—— 输入public interface

Input<T, SenderThrowableType extends Throwable>

{

<ReceiverThrowableType extends Throwable>

void transferTo(

Output<T,ReceiverThrowableType> output )

throws SenderThrowableType, ReceiverThrowableType;

}

Page 7: API 设计实例分析

7

接口整理 (2)—— 输出public interface

Output<T, ReceiverThrowableType extends Throwable> {

<SenderThrowableType extends Throwable>

void receiveFrom(

Sender<T, SenderThrowableType> sender)

throws ReceiverThrowableType, SenderThrowableType;

}

Page 8: API 设计实例分析

8

接口整理 (3)—— 发送者public interface

Sender<T, SenderThrowableType extends Throwable>{

<ReceiverThrowableType extends Throwable>

void sendTo(

Receiver<T, ReceiverThrowableType> receiver) throws ReceiverThrowableType, SenderThrowableType;

}

Page 9: API 设计实例分析

9

接口整理 (4)—— 接受者public interface

Receiver<T, ReceiverThrowableType extends Throwable>

{

void receive(T item)

throws ReceiverThrowableType;

}

Page 10: API 设计实例分析

10

标准使用方式(客户) 根据契约,然后可以制定几个输入输出( I/O )的标

准。比如:从文本文件中读取文本行后再写成文本文件。

这个操作可以静态方法中,方便的重用。 最后,拷贝文本文件可以写成:File source = ...

File destination = ...

Inputs.text( source )

.transferTo( Outputs.text(destination) );

Page 11: API 设计实例分析

11

拦截 [ 传输 ] 过程——过滤的 APIpublic static

<T, ReceiverThrowableType extends Throwable>

Output<T, ReceiverThrowableType>

filter( final Specification<T> specification,

final Output<T, ReceiverThrowableType> output) {

// create an Output that filters items

// based on the Specification<T> ...

}

interface Specification<T>

{

boolean test(T item);

}

Page 12: API 设计实例分析

12

拦截 [ 传输 ] 过程——过滤的使用代码下面的例子删除文件中的空行:

File source = ...

File destination = ...

Inputs.text( source ).transferTo( Transforms.filter(new Specification<String>()

{

public boolean test(String string)

{

return string.length() != 0;

}

}, Outputs.text(destination) );

Page 13: API 设计实例分析

13

拦截 [ 传输 ] 过程——传输类型转换的 APIpublic static

<From,To,ReceiverThrowableType extends Throwable>

Output<From, ReceiverThrowableType>

map( final Function<From,To> function,

final Output<To, ReceiverThrowableType> output) {...}

interface Function<From, To>

{

To map(From from);

}

Page 14: API 设计实例分析

14

拦截 [ 传输 ] 过程——传输类型转换的使用代码Input<String,IOException> input = ...;

Output<JSONObject,RuntimeException> output = ...;

input.transferTo(

Transforms.map(new String2JSON(), output);

File source = ...

File destination = ...

Counter<String> counter = new Counter<String>();

Inputs.text( source ).transferTo(

Transforms.map(counter, Outputs.text(destination) ));

System.out.println("Nr of lines:"+counter.getCount())

Page 15: API 设计实例分析

15

IO API 实现说明

Page 17: API 设计实例分析

17

成本收益分析

Page 18: API 设计实例分析

18

成本 分析好领域 需要让实现者理解保持一致 适当的文档让其它人了解你的设计

术语约定 分解方式

Page 19: API 设计实例分析

19

收效 DRY KISS (客户 API 简单,实现涉及较多内容)

分离的功能 资源维护 和 操作分离( IO 资源维护和 IO 操作分离) 核心功能 和 修饰性功能

分离功能之间功能方法参数关联起来,即外围功能持有依赖功能,组合方式(非继承)。

各个功能有明确的接口,且是组合的,所以可以方便Wrap ,方便拦截加入修饰性功能。

同时整理出了 API (外围接口)和 SPI (内部接口)

Page 20: API 设计实例分析

20

引申 客户类不需要继承框架内的类

1. 从框架继承来的代码属于框架2. 框架应该从客户类提取需要的逻辑拼装运行3. 客户类不需要从框架继承额外的逻辑

客户 观察不到的 不要 出现在 API 中 API 使用方式 是 客户直觉期望使用方式

Page 21: API 设计实例分析

21

参考资料 How to Design a Good API and Why it Matters(by Joshua

Bloch) http://lcsd05.cs.tamu.edu/slides/keynote.pdf The Little Manual of API Design

http://chaos.troll.no/~shausman/api-design/api-design.pdf Practical API Design: Confessions of a Java Framework

Architect http://www.amazon.com/Practical-API-Design-Confessions-Framework/dp/1430243171

Google Search http://www.google.com.hk/search?&q=api+design

Page 22: API 设计实例分析

22

The Design Process 《 The Little Manual of API Design 》第三章“ The

Design Process” ,可以实际操作:1. Know the requirements2. Write use cases before you write any other code3. Look for similar APIs in the same library4. Define the API before you implement it5. Have your peers review your API6. Write several examples against the API7. Prepare for extensions8. Don’t publish internal APIs without review9. When in doubt, leave it out

Page 23: API 设计实例分析

23