开闭原则-对扩展开放,对修改关闭。

开闭原则要求在扩展新功能时应当避免对旧代码的改动。但现实的开发中,新增功能多数情况下都要涉及到旧代码的改动,这主要是因为在业务刚开始推进的时候并不能很清晰的看出业务的拓展方向,因此通常情况下都不会进行预留扩展的设计(避免过度设计)。

当扩展需求出现时,就是开始重构原有代码的时机,而开闭原则就是指导重构的主要思想,在重构过程中,应将此次扩展的业务方向做一个通用方案的处理,保证下次再出现同类型的扩展可以做到不改动或少改动旧代码。

依据开闭原则做架构设计时,我们应该清楚要保护什么,可以通过分层来决定保护级别,最高层的保护级别最高,最低层的保护级别最低。低层级的改动不会影响高层。

层级的划分可以根据业务来划分,核心业务逻辑应该是最高等级,其他层级根据与核心业务的关联程度依次向下划分等级。这样的划分逻辑我们能够保证核心业务规则不会因为其他相关模块的改动而受影响。

接下来通过《架构整洁之道》(clean architecture) 中的一张图来解释一下分层设计

图 8.2
< I > 表示接口,< DS > (data struct) 表示数据类,数据类的特性是第一次访问的时候会创建类,后续则是对该实体的读操作(实体类特性也是如此)。空心箭头表示对应接口的实现,实心箭头表示依赖关系, A->B 则是 A 依赖 B,A 知道 B 的存在,B 对 A 一无所知。

正是由于依赖的这种特性,我们可以把被保护的代码,写到被依赖的类中,这样被依赖的类不会以为依赖方代码的改动而受影响。

上图中:Interactor > (database) > Controller > Presenter

关于图 8.2 调用链路如下:

这种设计 Controller、Presenter、Database 任何模块代码的改动,都不会影响 Interactor ,从而达到了对 Interactor 代码的保护,如果某天对 Presenter 中的 PDF View 进行改动出现了 bug,仅仅印象 PDF View 这一个功能,把 bug 进行最大程度的隔离,实现功能的稳定。

总结

开闭原则保证了程序的扩展性,同时用分层的思想设计架构,通过依赖保护核心业务逻辑,避免核心逻辑的频繁改动,隔离低层代码的改动影响高层。

如果你对架构设局同样感兴趣,推荐给你一本书《架构整洁之道》(clean architecture) 。这本书对架构设计的讲解十分深刻,相信你也一定会有所收获。