一、MVC加Event的混沌
在MVC中,我们当前有窗口:
WndA,WndB,WndC。
我们有事件:
BData_ChangeEvent(bool isOpen):B相关数据变更事件,isOpen为true时,打开WndB
CData_ChangeEvent(bool isOpen):C相关数据变更事件,isOpen为true时,打开WndC
我们有数据请求:
BDataReq:请求数据B,Res回调后发送BData_ChangeEvent
BDataReq:请求数据C,Res回调后发送CData_ChangeEvent
现在的需求是:我们打开WndA的时候,需要请求B和C数据,判断是否要开启WndB,WndC。
当监听到BData_Change为true时,打开WndB。
当监听到CData_Change为true时,打开WndC。
如果WndB和WndC都要开,WndC要等WndB关闭后再开。
做法:
WndA
监听
BData_ChangeEvent(bool isOpen)
CData_ChangeEvent(bool isOpen)
打开Wnd发送BDataReq请求
-->BData_ChangeEvent(bool isOpen)
-->isOpen为true-->打开WndB-->WndB关闭的时候,发送CDataReq请求
-->isOPen为false-->发送CDataReq请求,CData_ChangeEvent(bool isOpen)-->isOPen为true时,打开WndC
现在这个流程
WndA在请求BDataReq,CDataReq
WndB在请求CDataReq,看上去没啥问题,但是这种调用链很容易让代码变得很难阅读,也很难修改。
回调地狱,状态分散在各个事件监听器中。
事件虽然本身不会直接导致回调地狱,但事件驱动的异步编程模式很容易演变成回调地狱。
二、引入ViewModel
事件虽然本身不会直接导致回调地狱,但事件驱动的异步编程模式很容易演变成回调地狱。
于是让页面尽量不去依赖事件系统,引入VieModel层,页面更新通过ViewModel层去通知。
为WndA,WndB,WndC添加一个VieModel,把ViewModel取名为Holder,意为页面持有者。
流程变成了这样:打开WndA,创建ViewModel:AHolder。
AHolder-->
定义变量:
int m_getResCount; // 表示收到的消息数量,
List<Wnd> m_needShowWndList; // 表示要展示的页面列表,在展示前对其进行排序
同时请求BDataReq,CDataReq-->等待m_getResCount == 2;
当m_getResCount 满足条件后-->m_needShowWndList依次展示页面。
三、ViewModel解决的问题
引入ViewModel,把多个View的逻辑可以放到一起,减少回调地狱。
解耦ViewController,ViewModel可以为View构建表现数据。
一个ViewModel可以对应多个需要同类数据,表现不同的页面。
