什么叫好的扩展性?
我们天天讨论软件的扩展性,那到底什么是好的扩展性?怎么样的软件有好的扩展性?这里浅薄地谈谈我自己的认识,都是些简单的感想,欢迎拍砖,更欢迎指正。
要理解扩展性,首先要知道好的扩展性带来的好处,要知道从软件工程的角度来说,软件开发至少需要经历开发、测试、运维等阶段,一个刚开发出来的软件往往需要经历多次的测试、线上bug修复之后才能进入一个相对比较稳定的状态,也正因此一些常用的软件刚发布时会称为beta版本,也意味着新添加的功能或者特性没有经过实际环境考验,不是非常稳定。说了这么多,是想说明扩展性带来的好处:少改代码、甚至不改代码不仅仅是降低程序员的工作量,也意味着稳定,而稳定的程序才能带来价值和好的用户体验。这也是为什么越是实际经验多的人越重视扩展性,因为没有经验的开发者往往会天真地以为初期设计地不好只需后期多花点时间开发,而意识不到差的扩展性对其他流程和软件稳定性的损害。
说了扩展性的好处,那什么样的代码有好的扩展性呢?我认为好的扩展性一般通过两种方式实现:一种是对业务流程做了足够准确的抽象归纳,总结出了其中核心不变的流程,好比说电商业务,往往会经历浏览、下单、付款、配送等基础流程,如果把这些作为单独的模块并做好解耦,那下次需要在付款环节增加一种付款方式就不用每个模块都进行修改,只需修改付款流程即可,而如果对付款流程也做了足够的归纳抽象,抽象出了一个付款接口,新增加的付款方式只要实现了这个接口就可以无缝接入原来的付款流程,甚至如果还能进一步抽象出所有付款方式的通用属性,那一个抽象类就能进一步减少需要增加的代码(回到第一节,更少的代码带来的好处!),我们常说拥抱变化,其实意思就是需求永远是动态变化的,如果某个业务需求从来不变,那往往说明你的业务没有什么活力了:),而这种提高扩展性的方法核心就是抽象出你的业务里不变的,恒定的东西,对于可变的,提前做好接口,这往往需要对业务很深入地理解和高超的设计能力。另一种提高扩展性的方法是通过配置化地方式兼容所有可能的变化,前面说到需求永远是变化的,如果变动是不可预测的,那就必须要新增代码来解决,而如果变动是在可预测的范围内,往往可以通过配置化的方式去解决,就好比大家都熟知的Spring,Spring解决的是Bean的管理和依赖,他不可能知道你需要用什么bean,但是他知道你的bean都是java对象,所以只要确定的bean的class类型就可以实例化这个bean,你就可以用起来了,其他的依赖注入、init-method、pre处理器、post处理器等等都是在此基础上的高级特性。而这些对于所有bean来说都是一致的,所以只需要你通过配置文件告诉他你要用哪些bean就够了。而spring也正是因为对bean不“挑食”,不像EJB一样要求实现这个接口、那个接口才成为了如今最受欢迎的容器,这也进一步证实了“少写代码”有多重要。当然了,配置文件本质上也可以说是代码,所以这种方式和第一种方式其实只是更进了一步而已,并没有本质的不同。