上一篇(Android 设计随便说说之简单实践(模块划分))例举了应用商店设计来说明怎么做模块划分。模块划分主要依赖于第一是业务需求,具体是怎么样的业务。应用商店则包括两个业务,就是向用户展示applist,和下载app。第二是运行环境,在Android平台,有androidsdk提供socket等API支持。因此将模块大体换发了5个模块。(当然了图片加载可以额外提出,用开源组件去做,但是这里为了说明如何设计,暂不提到。还有下载也可以利用开源组件)分别是如下:
模块1 UI模块,负责展示信息和用户操作,主要类,RecommendActivity 负责数据展示和接受用户操作。RecommendInterface,负责底层数据回调。(这里只是举例,下载的就不在提及)
这三个类之间的调用关系如下:(我的viso貌似没有激活部分功能不能用只能口述了)
1 在RecommendActivity的onCreate里面初始化RecommendInterface实例RecommendBase实例。并将RecommendInterface注入到RecommendBase里面。
2 RecommendActivity随后给RecommendBase发送指令调用getPageViewData等方法请求数据。
3 当用户点击下载。gotoDownLoadApp的是时候,RecommendBase开始调用startDownloadApp。
好了UI模块的调用流程大体到这里。
模块2 调度模块。负责整体业务调度。主要的类包括如下:
巨复杂。不过我们继续理一下各个类调用的关系。
1 初始化该模块就是初始化Controller。Controller初始化ControllerDownLoadAppInfosInterface, 和ControllerBase。Controller将ControlelrDownLoadAppInfosInterface注入到ControllerBase里面。controllerBase初始化的时候初始化ControllerDownLoadAppInterface。
2 关键点,UI模块如何和调度模块交互。
2.1 RecommendBase里面初始化Controller和ControllerUIInterface。并将RecommendInterface注入到ControlelrUiInterface里面。
2.2 当RecommendActivity接收到用户指令时,RecommendBase接收到指令调用Controller.而当异步的结果出来时,ControllerUIInterface 调用RecommendInterface。并且由RecommendInterface 将UI界面更新给用户。(由此可见消息是从RecommendBase循环了一圈。)
3 页面数据加载。Controller接收到RecommendBase来的指令后调用ControllerBase启动加载模板和数据getViewDataByTempID。当底层获取到Temp和Data的是时候,会通知到ControlelrDownLoadAppInfosInterface, 这个接口在回调Controller。 Controller调用CreateViewData。之后会调用ControllerUIInterface调用将数据给到UI。
还有下载过程。这里就不在推演了。但是主要的是要看模块间怎么调用,也即是说怎么合理组合。
会发现,上层业务和自己的依赖接口是一套全面的完整的业务。而调度层也是完成了一套完整的业务。
第三个模块,数据解析模块,负责网络的applist数据和模板解析并组合。
关键点,如何和调度模块交互
在调度层的ControllerBase里面初始化该类DataWorkManager, 调度层有了模板和app数据后,调用setData,然后在调用getViewDataBytempId就可以或的模板数据。
也就是说,在调度层的依赖类里面,初始化自己的接口,并且根据依赖类的方法来实现业务。
但是这个是一个业务单元,不能实现整体业务。
第四个模块,网络请求模块。
关键点,如何和调度层交互。
首先在ControllerBase里面初始化NetTaskManager和NetTaskResultListener。并且ControllerDownLoadAppinfosInterface注入到NetTaskResultListener。
然后开始调用downLoadTemplateById()。异步的,结果由NetTaskResultListener反馈给ControllerDownLoadAppinfosInterface。由ControllerDownLoadAppinfosInterface来处理这个消息。
模块5 下载模块,还需要说么?我想不必了。
其实合理组合就看你在模块之间如何调度了。模块之所以提供接口,是因为第一,他的模块不需要其他模块所关心的。只要调用它的接口即可。第二,如果他的实现出现问题,问题解决也必然在这个模块里面。不会需要其他地方的修改。因此原则上无论模块如何改变,但不允许接口改变。
每个模块都有自己的依赖类,但是如果其他模块有类似的实现,则提供的接口必然和前者模块的依赖做出一个适配来实现无缝连接。上面的例子都是很简单的。基本上没有太多的需要依赖和接口之间的适配,但是实际工作中多着去了。
最后,很抱歉的说,上面的例子多有纰漏,很多地方只是说明说的很简单,很粗糙,有冗余,甚至有错。仅仅希望能有所获益。