前言
代码每个人都会写。但是,能把代码写的优美,把结构设计的足够灵活,并且让人赞叹的人却很少。尤其在中国这样的大环境里。大部分人都是为了生活而奔波。编程只不过是一份工作而已。所以,我想,你肯定也曾经像我一样,看到很多想骂娘的代码。这些代码通常被称之为面条代码,所谓的面条代码,就是写的像长妈妈的裹脚布一样,又臭又长。让人理不清,理还乱,是离愁,别是一番滋味在心头。
笔者工作只不过短短几年,但从来不敢轻视编程,一直视编程为一件非常神圣的事情。从一开始,我就严格按照代码格式去构建我的代码,最初的时候,拿开发工具格式化基本都没有变化。现在想想,正是源于当初对待编程战战兢兢,如履薄冰一般,才有了现在非常漂亮的代码习惯。在笔者工作的这几年里,每天和Code约会的时间最长,先后掌握了Java,C++,OC,Swift等语言,工作中接触最多的还是Java语言,但从其他语言中我也吸收了很多营养。鉴于笔者这些年的经验,希望写一篇文章讲一讲接口的设计,笔者水平有限,文章只当是抛砖引玉,如果有更好的设计,请在文章下方留言告诉我。
避免过度封装
这是我想说的第一点,很多人喜欢这样封装,把接口局限在仅仅解决一个特定的问题上面,失去了代码的灵活性。而且,也容易出现面条代码,让人不知所云。笔者的工作中已经遇到了很多这样的问题,一个接口被写的仅仅用于解决当前问题,当笔者试图增加其扩展性时,发现为时已晚。任我移花接木,甚至是斗转星移都无法使其逆转。遇到这种情况,笔者常常是另辟蹊径,将垃圾接口代码标注为@Deprecated,重新写一套接口。为了防止过度封装,在设计接口的时候,我们应该考虑以下几个问题:
- 我们需要解决什么问题
- 问题的核心是什么
- 应该怎样设计,可以方便客户程序员扩展
第一点,我们需要找出我们将要解决的问题,这个看似容易的工作,其实并不容易,很多人即便遇到了问题,依然不知道自己到底要解决什么问题。只是使用一些面条代码,饮鸩止渴。最终,害人害己。
第二点,我们需要找出问题的核心,一定要记住,是找出问题的核心,而不是直接解决问题的方法。如果你只是找出直接解决问题的方法。那么,这个代码一定是不具有任何扩展性,也不能称之为接口。我们只能认为,他写了一堆代码,解决了一个问题。
第三点,一定要充分考虑接口的可扩展性,这就要求在做接口设计的时候,要站在客户程序员的角度去想问题。他要怎样使用我的代码,他会如何扩展我的代码。所以,记得要该放手时就放手,不要把过多的工作写在你的接口里面,而应该把更多的主动权交给客户程序员。
见名知意
接口中,方法的设计一定要力求简洁,而且要见名知意。如果笔者的同事有在注意笔者编码的话,一定会发现,笔者在设计接口的时候,花在名称的定义上时间是很长的。
这里举一个简单的例子,在Java语言中,单例的方法名几乎已经是习惯了,叫做getInstance()。可是,仔细想一想,getInstance()真的可以表达单例的意思吗?答案是:完全不能。getInstance()更像是工厂方法的命名。而笔者认为OC语言命名单例的方法就高明了许多,iOS程序员一定熟悉sharedInstance()方法,共享的单例。一下子就将单例的意思表达的简明扼要,如流水般清晰自然。
这只是一个简单的例子,笔者希望告诉大家,在设计的接口的时候,接口的名称一定不能偷懒,拿发起POST请求的方法名命名。如果你称之为sendReq()。那么,请问客户程序员怎么知道这是要发起GET请求还是POST请求?客户程序员在使用这个方法的时候无疑要点击进入源码查看,大大增加了开发成本。
因此,笔者认为,一个好的的接口方法名,是接口设计中成功的一半。而要想让接口设计的优雅,自然,请继续关注下面的文章。
仅把必要的工作交给客户程序员
什么叫必要,这里可以理解为,当前无法估计的操作。比如转换到具体的数据类型,而具体是什么类型,接口设计者是未知的。那么这个操作就可以交给客户程序员。同时,要注意的是,不要给客户程序员过多的工作。过多的工作设计就意味着这个接口的设计是完全失败的。同时,也不符合接口的概念。充其量也只能称之为解决一个问题。所以,设计的时候要记得尽可能简化客户程序员逻辑,使接口设计能够看起来简洁、漂亮,而不至于被接口的复杂性所吓倒。
充分保证程序的可扩展性
其实做到上面几点,程序的可扩展性基本已经有了保证,但还有一些工作必不可少。在设计接口的时候,要充分考虑是否需要被重写,如果需要被重写,考虑标注protected。否则,标注private。对于不明确的方法,请慎重考虑,被重写的可能性。如果几乎为0,则不考虑其被重写。另外,在保证充分可扩展性的前提下,也要保证数据的完整性,不可因为客户程序的错误访问,导致接口设计出现异常。所以,适度很重要,不要因为扩展性而丢失了数据的完整性。
简洁
接口的设计一定要充分简洁。这很重要,见过很多程序员,为了保证接口的充分可用性,设计了一堆参数。但其实,大部分情况下客户程序员只需要一两个参数即可。这样的设计就违背了接口设计的简洁原则。会让很多客户程序员望而生畏,放弃对该接口的使用。或者进行二次封装。所以,简洁设计是接口设计的一个重要原则。可以在接口的内部实现中,使用复杂冗余的参数,而在暴露给客户程序员的接口中,一定要尽可能简洁。
百分比原则
在接口的设计中,难免要设置一些默认操作,在设计默认操作的时候,一定要充分考虑用户的使用习惯。比如接口的操作有两种,要充分对比这两种操作频繁度。这里假设操作有A,B两种,如果A操作更为频繁,则应该将A操作设为默认,反之,则为B。这里可以认为A操作的百分比超过了50%,故取其作为默认值,笔者将其称为百分比原则。即根据操作的频繁度依次排名,取百分比最大的操作为默认值。
文档表述要清晰
良好的接口设计,离不开清晰的接口文档表述。文档表述一定要足够详细,使客户程序员充分知道该接口的用法以及需要注意的问题。这一点是很多接口设计者容易忽略的。但这一点的重要性,笔者认为甚至超越了上面所有点的总和。
总结
接口的设计是实际开发中必不可少的一环,也是最重要的一环。良好的接口设计能够起到事半功倍的效果,而杂乱无章的接口设计有时甚至会造成无法挽回的损失。因此,在设计接口的时候,请慎重考虑上面的设计原则。有一句古话告诉我们,磨刀不误砍柴工,说的就是这个道理!