本实践目标
- 熟悉air20x的sys.dispatch, sys.reg API
- 思考如何让我们业务模块的功能更内聚,尽量不“掺杂”非本模块的代码
- 思考尽量标准化,基于规约构建,不因外部业务的变化而造成“散弹式”修改
- 感受luat的sys module在事件处理的设计带给我们的感动体验
- 再次梳理一下知识点,Design pattern - Observer Pattern
相关资料
- 《Luat 脚本开发指南V2.x》
- 《lua扩展库V1.x》
- 事件驱动架构
- 设计模式之观察者模式
场景需求
好遗憾,难倒不需要硬件连接了吗 >_<
硬件当然是必须的,因为我们需要运行在luat平台上嘛,只是硬件的准备会更加简化,只需要一个air202的实验板 + micro usb线就够啦:)
我们假定我们的产品功能特性如下:
- 通过传感器对温湿度进行检测
- 将数据报告给业务服务器,支持socket,mqtt,http
- 将数据显示在设备界面上,支持led,单色lcd,彩色lcd
- 当温湿度达到警报阈值,进行报警操作,继电器触发,或 短信报告
场景一: 特性,外设是需要支持选配的
- 需要上报服务器,但仅仅需要http
- 不需要用户界面
- 没有继电器,只需要 短信报告
场景二: 针对某定制项目需要增加当前产品不包含的特性
- 需要增加对空气中CO2浓度的检测
- 对设备界面设备有要求,需要使用串口屏
针对以上的特性要求和场景,我们的目标
- 每个模块代码开发的时候尽量不需要考虑其他模块
- 如果增加新的特性,尽量不用修改原有代码,至少是非相关模块的代码
- 对于特性的增减,尽量的简便,而且可减少测试的负担
接下来我们就看看luat的事件处理可以给我们带来什么令人惊喜的体验 :)
这当然不会是唯一的方式,希望可以有更多的讨论,让我们找到更多更优雅的办法
初心依旧,抛砖引玉:)
要点分析及其说明
-
固件
请使用最新版本的固件:Luat_VXXXX_Air202.lod
-
产品的特性清单
传感器模块 sensor
- 温湿度检测
- CO2浓度检测
设备显示模块 display(UI)
- led
- 单色lcd
- 彩色lcd
- 串口屏
业务上报模块 reporter
- socket
- mqtt
- http
报警模块 alarm
- 继电器处理
- 短信报告
针对这些功能特性的实现,我们可以考虑的方式应该会有很多种
-
可能不那么优雅的方式
使用全局state,通过flag进行这些特性的开关
使用状态机,通过switch case进行特性路径的切换
这种方式也可以干净的实现特性,但也许稍微的劣势是将“开关”和“切换”的逻辑与代码有混杂在一起 -
可能优雅些的方式
将各个模块的实现抽象出接口,模块间交互完全通过接口规约进行,将模块的具体实现细节隐藏。
如果需要增加新的特性实现,只需要实施对应的实现就好
针对对应用尺寸敏感的需求,还可以通过条件编译进行选择性编译(这个也许稍微复杂一点) -
luat的事件机制给我们的一种选择
首先我们将模块进行简单的分类,生产者和消费者, 生产者负责生产商品,消费者负责消费商品,luat的事件机制在其中充当销售员的角色,生产者和消费者无需进行直接的对话
生产者
此处生产者是唯一的, 传感器模块 sensor
消费者
此处的消费者是开放的,设备显示 display(UI), 业务上报(reporter), 报警模块(alarm)
也许将来会有我们现在不会考虑的,将数据记录最新1000条到SD卡(recorder)
此处连接生产者和消费者的商品是什么呢?
luat的事件(event)
在此基础上,我们就可以将事件(event)作为一个规约设计的入口,各个模块间通过event进行交互
而event在各个模组间的交互,就完全托管给luat平台 :)
- luat如何产生一个事件(生产商品)
sys.dispatch('SENSOR_EVENT')
- luat如何侦听一个事件(消费商品)
local function consume()
print("//TODO consume logic")
end
local procer = {
SENSOR_EVENT = consume,
}
sys.regapp(procer)
-
借助luat的event,我们的模块可以是完全独立的
我们将以上的设想用简单的描述如下 :
-
luat的event模式带给我们的好处
- 避免散弹式修改,例如:实现一个阿里云的上报需求,我们可以仅在reporter模块做处理,对于其他模块应为透明
- 这些模块可以更便利的复用到其他项目应用中
- 如果面临应用尺寸的压力,需要精确的按照项目需求选择逻辑,我们可以在main中的require作为一个切入点,而不用担心是否模块的选择会让代码编译或运行失败
代码地址
https://github.com/wingpengfei/luatcookie/tree/master/air20x/src/event
这里的代码很简化,就是简单体验了event的生产与消费。
希望和大家互相学习,一起进步:)