再谈开闭原则

最开始了解设计模式之开闭原则是在6年前,那个时候我还是在校大学生,我是读《设计模式之禅》了解到它的。开闭原则是说,对扩展开发,对修改关闭,当时我看书的时候还不太了解它的含义,只知道这是设计模式最重要的原则,其他5大原则(如最小接口原则、迪米特原则、里式替换原则等)都是为了更好的实现开闭原则而总结出来的一套方法论,而书中说的23大设计模式都是基于这些模式的实践。

今天我又一次感受到了开闭原则的牛逼,我感受到,它不仅仅可以用在实际的代码编写上,对整个系统的架构都有指导借鉴意义。

我目前负责的是我司自动化测试的执行流程,今天有个需求是要给各个手机agent server添加一个doctor的诊断命令。目前的架构是这样的,有3个手机agent server,分别是Robotium、UIAutomator和iOS的XCUTest,执行端这边负责建立socket短连接与这3个agent server进行通信,目前在我写的一个AgentManger来协调管理他们,这部分已经完美运行一年半了,改动很小,需求是现在要添加一个新命令doctor,然而我发现这三个agent server都通过socket连接,但他们的通信内容的协议居然完全不一样,Robotium agent server这边是以“OKEY%s”来格式化返回值,单不看整个的通信架构是否合理,就这个返回的字符串我就很想吐槽,哪有这样的?!通常都是用统一格式的JSON来表达返回结果的,不管是几个agent server,都可以用一套处理模式来处理,甚至分出一个独立的工程模块来做这件事情,而UIAutomator Agent server它的返回值的结构则是{‘success’: true, ‘msg’: ‘xxxxx’}的一个json结构,这个表示也很糟糕,虽然是json的,但是只有true和false两种状态,如果你说你把它改一下不就行了吗,但是你要知道,以往的工程已经积累了几十个接口了,如果去改它以前的通信结构,那么会改动特别大,整个程序要进行回归测试才可以重新上线,所以从一开始就设计出统一的通信协议是多么重要,而如果是在统一的模块中处理的话,那就更容易了,只要在这个模块中更改协议就好了,做少量测试就可以知道你的改动是否覆盖所有的接口,这样可以大大减少后面的工作量!

再联系到我们的开闭原则,原则说,要对修改关闭,对扩展开放,上面的那个垃圾通信协议结构,你要对它进行修改是无比的困难,而添加新的接口,又会让这样的垃圾结构继续存在,当某一天你发现这样的通信结构无法满足要求时,你会发现你必须得修改,也就是要重构了。所以从一开始设计出一套能够更容易扩展,无需修改的结构是多么重要!