API设计原则:正确、好名、易用、易学、够快、够小。但我们从来不缺原则,〜〜〜
Interface
1.The Importance of Being Use Case Oriented,一个接口应当是一组方法的集合,方法是否能放在一起、最重要的依据是通过用测和使用场景去判断。更具体地是The Input Params Oriented,输入参数一定与接口相关。
2.you can't know what users of your API will do with it.但了解接口的可能调用者情况,预测使用场景,考虑性能压力。使用场景包括:WHO、WHY、WHERE、WHEN、HOW等,e.g.[APP团购单详情页][为了获取商户详情][在团购列表页][当该用户未购买过该团购单时][通过传Enum.Type.Mobile&shopId方式]调用shpinfo.bin接口。性能压力,各渠道调用QPS等。另外还需考虑线程安全,如synchronized等。
3.版本控制。 bring out one or more 0.x versions. create a new API with different package names. 不稳定版本、采用小号方式,让用户知道”我是坏人“。如果历史包袱太重,那就干脆换个包,令新、旧API和谐共存。另外,你永远都可以新增API,但永远都不能删除。
4.考虑提供批量处理方法,批处理可以有效减少网络传输、增加处理效率等。应当在批处理之前定义单个操作。
5.接口应该保证幂等性,异步调用超时、可保证重复调用,如AddConsum(serialNo, user, product, money),增加serialNo避免重复提交。
6.屏蔽底层实现细节。不要过度地具体说明方法的行为,如:用Map、List替换HashMap、ArrayList等,Exceptions should usually be unchecked。
Class
7.接口类使用到的所有实体类/Bean等类,为之提供无参数的构造函数。 一些框架如hessian需要bean有无参的构造函数。
8.接口方法中避免重载的方法,即避免有两个方法同名,重载的方法一个方面在hessian接口调用会有问题(其他协议的远程接口可能也有问题),另一个方面同名的方法影响代码可读性。 比如这样的接口是不合适的。
9.接口中用到的自定义类, 实现序列化接口,提供toString()方法; Java要提供toString()方法,并继承Serializable接口,生成Serial Verion UID。考虑实现Comparable等接口。
10.禁止使用继承,在实现类前加final关键字。继承违反了encapsulation特性,子类必须知道父类的实现特性。
Method
11.采用合适的参数和返回数据类型。如:使用BigDecimal或double代替float(32bit),使用更加灵活的接口数据类型作为输入参数,尽量使用Enum代替String作为类型区分参数等。
12.避免过长的参数列表,专家建议不超过3个,欢迎拍砖。有两种技术避免过长参数:a.将一个多个步聚的方法拆分细化,b.创建包含这些参数的帮助类。
13.避免集合返回NULL,应当返回空对象。但对于单个对象,如果空对象不能够方便地表达“值为NULL”的状态,则返回NULL。
附:
GOOGLE首席软件工程师Joshua Bloch:《How to Design a Good API and Why it Matters》《深入JAVA虚拟机》的作者Bill Venners:《Interface Design》