(一)引言
计算机世界即是现实世界的抽象,计算机世界的很多模型和规范都是对现实世界的抽象建模构建而成。反之,一些计算机天才在计算机领域的创新,也可以借鉴改造成利于现实世界文明发展的规则。代码人生,便是由0、1探索世界的过程。
(二)介绍
在现实中,我们要把笔记本屏幕的内容投影到大屏幕上,只需要把笔记本和投影仪用转接线连接。这里我们可以理解为投影仪提供了一个接口,这个接口接收指定的外部信号,输出内容,内部如何运转使用者无需了解,出了问题交给设备提供者维修即可。
(三)好处
上述例子给我们的直观感觉就是方便,投影内容只需要一台设备,再遵循指定的方式使用即可。对应到编程过程中,面向接口编程也有许多好处,按照我目前的理解,列出以下几点:
-
代码分层,利于后期扩展。假设项目里有一层数据持久层是用mySQL实现的,如果controler层都是直接使用SQL语句的方式来取数据,这样后期要将持久层改为CoreData,那所有的controller都要修改,想想都觉得恐怖。如果采用面向接口的方式,所有controller存取数据的时候都经过一个中间层,这个中间层只提供controller需要用到的接口,至于内部是用什么方案使用者无需关心,这样就灵活了不少。
-
接口抽离,利于单元测试。在开始编码前先将需要用到的接口定义好,自上而下定义接口,自下而上实现接口。接口实现了就可以进行测试,输入各种参数检验是否按照预期输出。最后只需将经过测试的所有接口按照事先的流程组装起来,组装后还需要测试整体的稳定性,例如时序和竞争的情况。经过这样的测试后才能保证代码的健壮,也能避免整体测试时还要排查接口的正确性。
-
功能归类,利于维护和排错。假设业务中有一个下单的模块,其中有个情况是一些特殊类型的订单有优惠,下单的时候要判断,下单成功后的页面展示也要判断下,可能还有很多其他分支要使用这个判断,如果没有使用接口,那么到处都是(
if order.orderType == kSpecialType1
)的判断。代码刚写完,产品过来说业务变更了,特殊订单要增加一种类型,好吧,你一边在心里吐槽一边开始全局搜索然后一个一个替换,替换到一半,测试过来找你说有个bug,你看了下现象,比较奇怪,于是开始debug。虽然你已经很仔细在替换了,但是一不小心还是漏掉了一处,于是bug埋下了。要是使用接口的方式,你在Order里定义了一个接口isSpecialOrder
,所有使用到的地方都是用[order isSpecialOrder]
来判断,后期要修改就只用修改这个接口的实现。集中到接口中实现还有一个好处是排查错误的时候比较好调试,以订单作为例子,如果页面显示了错误的订单,我们可以大致猜出是这个判断的地方出问题了,如果集中在一处,我们只需在这里断点调试便可查到原因。分散到各处的话,我们找到对应显示的逻辑都要一会儿,人的大脑能同时处理的信息有限,我们应该尽量让琐碎的逻辑集中到同一个地方,每次查找时都条件反射似的找到这块区域,这能大大提高效率。
(四)总结
以上写了这么多,主要就是为了强调面向接口的必要性,好处主要是:
- 面向接口的分层处理减少了平台相关代码适配迁移的成本,例如iOS8以后访问相册可以使用PhotosKit,iOS9以后访问通讯录可以使用Contacts Framework,如果要同时适配新老版本的系统api,可以在中间层处理相关逻辑,controller只通过中间层的接口来存取数据,这样即使以后苹果又有新的api来获取这些资源我们也不需要再修改controller,只需要在中间层处理即可。
- 集中处理带来的效率提升。将琐碎的逻辑代码集中到一处方便快速查找,出错了也只用修改一处不至于遗漏。
软件构建是一门艺术,前人总结了很多宝贵的经验,我们在平常的实践中应多思考,以写出易读高效的代码为荣,以随意编写代码完成需求为耻。
如果您觉得本文对您有所帮助,请点击「喜欢」来支持我。
有任何疑问都可联系我,欢迎探讨。
网友评论