最近对项目代码做了一些更改,主要的改动是对整个界面框架的改变,因为以前写代码的时候,为了完成功能,没有从上帝视角来思考软件的界面设计,完全是需要这个功能了,怎么可以做到?好,就就这样吧,为了完成功能而对界面不停的修修补补,这样带来的主要坏处有很多:
一是,后续功能加进来的话,需要考虑的地方会越来越多,因为前面的代码耦合程度很高,比如onStart回调,有些事情,既可以在Activity的回调里面去做,也可以在Fragment的回调里面去做,既可以在这里做也可以在那里做,新增加一个功能进来的时候,不得不考虑在所有可能的地方都要检查一遍,然而这样可能还是无法完全考虑到所有情况,最后出现遗漏导致测试的时候报bug修改。
二是,维护现有的代码也很困难,比如测试或者产品突然冒出来一个新想法,要把原来的效果改成一种别的效果,看起来似乎不是很难,但是实现的时候发现真的很麻烦。。比如之前支离破碎的fragment,连我自己都不知道这个title到底是属于fragment还是属于acticity,整个界面的动画切入切出也很难做,因为他们根本就不是一个整体的。。
三是,代码写起来很丑。比如onbackPressed,需要先判断(xxxFragnemt != null ,xxxfragent.isvisiable(),xxxPopwindow != null)之类的鬼东西。。实在是太难看了。。
现在改动主要是考虑到了上面几点,主要的变化是,
1.界面和数据分离,比如界面A更新的时候,它也不需要考虑,我是不是也要更新B了,这些都抽出来交给上一层数据结构去处理。例如如果activity包含有很多fragment的话, 那么把这个activity单独抽出来,负责保存数据,在android的设计中,activity和fragment之间的消息通讯有很完整的解决方案,这样做也把activity从交错复杂的界面中解放了出来,它只负责保存和同步数据,通知界面更新状态,而fragment则只负责界面,显示数据。原来属于公共部分的界面,比如title,bottom现在分开到各个fragment里面去了,所以也需要一种同步的机制,这种需求的话交给activity去控制,比如观察者模式之类的,这是完全可以做到的,现在我只是暂时粗略的维护了一个fragment的链表,数据更新的时候依次通知各个子页面就可以了。
2.想办法提取一些公共的特性,把它们都放到基类里面去做,因为界面之间的耦合度降低了,因此很多交互的需求都可以抽象出来成为接口,让各个界面自己去响应对应的调用就可以了,比如前面所说的onbackPressed回调,现在activity根本就不用管这么多条件了,直接一次调用子界面的接口就可以了,而不用自己去检查管理应该调用哪一个界面,怎么响应。当然,因为这个交互的特殊性,只能有一个界面去响应,所以暂时改成了这个样子:
for(fragment x:fragmentList){ if(x.myBackPressed() ){break ; } }
这样改之后感觉逻辑处理上确实简单了很多,具体效果还有待确认。仔细想想,这一套似乎和MFC那一套十分相似。。。这次的改动也让我觉得,android和windows确实很多相似的地方,比如消息队列,比如这次的activty和fragment的关系,就和windows里面的各个窗口的关系差不多,只不过android把它抽象出来了而已。日子似乎又回到了我刚开始看PC客户端代码的时候,David跟我说,你主要需要弄清楚消息是怎样流动的。现在想想,一个框架的设计,的确最重要的就是消息怎样流动,怎样响应。它的结构清晰吗?它需要被消耗掉吗还是要通知到所有的地方?界面之间的消息,需要怎样相互通知?界面和框架之间,需要怎么通知?界面状态更新直接和同步,需要怎样通知?这些都是需要认真考虑的问题。