对接口设计的一个小看法

与另一产品线的同事们讨论对接接口,对一些领导和架构师的某观点十分不认可。内容如下:

  • 接口中的数据类型全部是String,不要出现Int等其他类型,理由是统一好处理。
  • 接口中Array类型请用String替代,值用逗号分割,理由是接口中不应该出现数据结构。

我强烈反对上述观点。我粗浅的认为设计的基本原则是世界是什么样子,你的设计就是什么样子,这是好设计的前提。设计原本很简单,就是对真实世界的合理抽象,不是人为扭曲。

接口设计的第一原则是,让使用者易懂易用,如果必须看文档看注释才能使用,那这个设计是失败的,是对码农代码的侮辱,还做个什么架构师?

对于第一条:

  1. 调用者和接收者都将进行类型转换,不可避免的必须对转换异常进行处理,代码臃肿丑陋。
  2. Null值如何处理,对于本该是Int的值,不传可以默认0,这造成接口中所有参数必须都传值。
  3. 给后来读代码的人造成极大的困惑,有些明显是Boolean类型的值。

对于第二条:

  1. 分隔符怎么通知使用方,必须写文档或注释吧?
  2. 不但没有避免双方人为沟通,反而增加沟通成本。如果接口中是Array,双方仅通过接口就已经明白对方的意思;如果是个拼接的字符串,实际上这个沟通成本后退到双方各自更深层次的代码中,换句话说,在更深层次中双方耦合了,而不是只在接口上耦合。
  3. 全部同上。

举个例子,其中有一个接口是这样的:

public List<Map<String, Object>> jsonPersonGetAll(String eid, String begin, String count) throws Exception;

这个接口毛病很多,我吐槽一下。

  1. 方法名不能传达准确的意思,json 在哪里?输入 json 还是输出 json ?
  2. 返回值是集合套集合,不应该是对象吗?想取一下 Map 中的 photoUrl 值,key 大小写不能错,取回后还得强转成 String!
  3. begin/count 这两个变量可以看出,该方法是分页查询某 eid 下全部 person ,那么 begin/count 用 Int 更合理吧?
  4. 抛出Exception,咋不抛的更大呢,为什么不抛出具体的异常,这让上层如何处理?

上文中所谓的 ‘接口设计原则’ 、 ‘基本原则’ ,全是我个人的观点,水平有限,欢迎拍砖。

评论