为什么会有这篇文章

起因是数日前,一同事跑来和我说,他感觉我们现在的项目结构非常烂,希望能够重新设计,我说你说说看。听罢,血压暴力拉升。原因是项目本来有多个事件回调函数,如 event a 对应 callback a,event b 对应 callback b,以此类推,且不同的event有不同的参数。同事说:“我想要统一成一个事件回调,用 void* 传参数,在处理函数中根据传入的参数头进行类型判断和解析”。我直呼这是傻x行为,同事不服,且不接受我的说法,加上我最近在刻意训练设计模式相关的内容,于是整理了相关笔记用于反驳。我再把笔记重新排版,于是就有了这篇文章。

单一职责原则

每个回调函数只处理一种特定事件,职责清晰,修改事件A不会影响到事件B。 如果统一处理,多个事件只要有任何变动,都要修改它们共用的回调函数。

把所有事件处理逻辑都放到一个函数里, 会让这个函数变得非常混乱,这违反了 单一职责原则,这样的函数被称为“上帝函数”:它们知道的太多,做的也太多,最终会变得巨大且难以维护。

接口隔离原则(Interface Segregation Principle,ISP)

一个event用一个callback,函数有清晰的签名。如果合并,需要处理复杂的类型,还容易失去编译器的类型检查。

接口隔离原则:调用方不应该被强迫依赖于它不使用的方法或接口。也就是event a的发布者,不应该需要知道event b的存在;event b的发布者也不应该需要知道evnet a的存在,每个发布者都应该只需要知道自己所涉及的、最精简的接口。

如果合并,合并后的函数签名会类似于 callback(eventtype type, object data),这是一个胖接口(Fat Interface)。现在event a的发布者,被迫依赖于 event type 这个 枚举 和 object 这个 通用数据容器,这违反了 ISP的核心:为了调用一个函数,强迫一个简单的事件发布者去理解一个复杂的、包含了它不关心的其他事件信息的胖接口。

对修改封闭,对拓展开放

已经被稳定使用的代码,不应该被随意修改。 保证稳定可用的代码不背随意改动,是保证整个系统质量的基石。如果业务需求变化,我们应该在不改变原有代码的基础上,通过增加新代码的方式来拓展系统的功能。这就是:对修改封闭,对拓展开放。