很多开发框架都使用一个全局的事件派发器承担模块间的消息传递工作,原因是事件机制(也就是观察者模式)将依赖反转过来,不再是“我需要什么我就获取什么”了,而变成了“别人可能需要什么我就提供什么”,使得模块间不再直接产生依赖,所有依赖都集中到了全局唯一的且永远存在的对象上(就是全局事件派发器),于是依赖即使存在也没什么卵用了
Olympus也继承了这样的志向,提供了一个全局唯一的事件派发器,但却有些不同
Olympus的事件并不是直接使用js的事件体系,而是自己实现的观察者模式。原因有二:
- js的事件绝大多数情况是依赖于DOM节点的,而全局事件派发器在设计上与显示无关
- 即使可以通过实现接口而不是继承基类的形式将事件与显示分离开,js事件也是基于DOM库提供的事件接口,如果放到NodeJS环境可能就不能用了
正是基于上面两点原因,即使Olympus已经被设计成前端开发框架,本人仍旧不想让它与DOM产生过多耦合,算是本人在设计上的一点点洁癖吧
在core对象、Model实例、Mediator实例、Command实例上都有dispatch方法,调用之即可将本地消息派发到指定的内核里。其中:
- 在core、Model、Command上派发的消息总是属于全局消息
- 在Mediator上派发的消息属于模块私有核消息,但最终会冒泡到全局核上
Olympus并非直接使用事件派发器,而是在上面包装了一层逻辑,使得开发者不仅可以直接监听其上流转的本地消息,还可以通过各种便捷方式对本地消息进行响应
所有Olympus本地消息的监听方式包括:
- 通过API显式监听消息,也就是观察者模式的传统使用方式
- 通过Command响应本地消息
- 通过@MessageHandler装饰器响应本地消息
在相对复杂的业务中,或许一个全局的事件派发器并不够用,例如经常出现某个模块派发的消息不希望其他模块接收到,收到会出错。这时就需要多个事件派发器了,于是多核的概念应运而生
- 全局核与每个模块私有核组成一个一级树状结构,全局核是树根,模块私有核是树叶
- 消息的流转过程遵循“冒泡”方式,即下层消息会逐级向上转发,直到到达全局核
- 消息的流转过程没有“捕获”方式,即上层消息不会向下转发
- 目前核的层级只有两层,未来可能会扩展到多层,但依旧会遵循上述流转规则
这种方式可以有效解决模块私有消息的问题,一个模块私有核的消息不会转发到另一个模块私有核上,但如果你想,可以通过全局核监听所有消息