标签: android 架构 轻mvp MVCP kotlin
先看代码吧0。0
①数据获取代码样例
model 层
class UserListRequest(
page: String? = null,
pageSize: Int? = null
) : ListRequestData(null, page, pageSize, USER,"getList")
presenter层
ApiRepo.post(UserListRequest()).subscribe()
//切换数据源
CacheRepo.get(UserListRequest()).subscribe()
DbRepo.get(UserListRequest()).subscribe()
SpRepo.getBean(UserListRequest()).subscribe()
以上就是调用一个接口所需要做的
- 创建请求类request
- 发送请求
- 创建响应类response(可选)
不需要为每个具体请求添加额外的方法。
②基类、工具
以Http请求为例
model基类
//列表请求基类
open class ListRequestData(
val condition: T? = null,//condition是具体查询条件
val page: String? = null,
val pageSize: Int? = null,
module: String, //请求模块名,自动写入到请求地址中
method: String //请求方法名,自动写入到请求地址中
) : RequestData(module, method)
//通用请求基类
open class RequestData(
@Transient val module: String,
@Transient val method: String
)
仓库repo
//封装成rx模式,将数据转换为BaseResponse,用户只需要传入request请求,就能得到response
object ApiRepo {
fun post(request: RequestData, autoAsync: Boolean = true, needCache: Boolean = true): Observable {
return HttpUtils.post(request)
.compose(DealTransformer())
.autoAsync(autoAsync)
}
}
工具类HttpUtils
internal object HttpUtils{
fun post(request: T): Observable {
return encryptRequest(request).flatMap {
HttpManager.create(BaseApi::class.java)
.post(request.module, request.method, it)
}
}
}
retrofit统一接口
//使用retrofit2,非标准RESTFul协议,只保留post,
internal interface BaseApi {
companion object {
const val PREFIX = "api/"
const val MODULE = "module"
const val METHOD = "method"
}
@POST("$PREFIX{$MODULE}/{$METHOD}")
fun post(
@Path(MODULE) module: String,
@Path(METHOD) method: String,
@Body body: RequestBody
): Observable
}
不管使用的是http请求、数据库、缓存或是其他数据源,我们都可以用统一的方式调用处理,同样的model,可以适用于http、lru、db、sp,从而实现,切换数据源而不需要做其他改动。
静态工具类代替多态,提升了性能,也减少了工作量。
补充
在这种方式下,一般的操作都已经适用。如果有特殊情况需要特别处理,那也就是另外一个XXXRepo的事。
如果你不想用通用的方式,而是按照模块划分Model,也是可以的
这时候就是我们常用的多态了,kotlin以委托的形式实现
interface IUserApi {
fun getUser(request:UserListRequest)
}
class UserApi : IUserApi {
override fun getUser(request:UserListRequest)=...
}
//不是省略,而是真的只有这么一行
class UserRepo(val api: IUserApi) : IUserApi by api
//调用方式
UserRepo(UserApi()).getUser(UserListRequest()).subscribe()
这种方式,明显比使用静态类麻烦了,如果有特殊需求可以考虑,但不建议使用。
下期预告
由于篇幅问题,这里只有数据请求的代码,还有界面相关的完整代码将会在下一篇出来。源代码会在整理好后放到github
后续计划
- 一般界面模板
- 列表界面模板
- 空界面、错误界面、加载中界面、自动分页
- BaseObserver、BeanObserver、ListObserver、ConvertListObserver、SimpleListObserver
- IListHelper、CacheListHelper、SimpleListHelper
- 快速开发,10秒完成界面代码框架
- 使用脚本自动生成通用代码
说一些废话0,0
1. 起因
在新项目来临时,手底下只有一个新手,而本人却在其他项目分身乏术的情况下,改进项目架构,成了避免日夜加班的唯一手段。
重复的劳动力操作,不仅会让程序员加班,还会让程序员产生消极心理,限制程序员的成长。浪费生命可耻啊!!所以,消除重复性劳动,才是我写这文章的最主要原动力。
2. 现状
对于现状Android流行的架构设计
简单的就是MVP,但是冗余代码太多,带来的可复用的好处却是很少见。
复杂的就是各种插件化,路由,解耦架构。但是这些架构,都是更加适用大型项目,不符合创业项目的开发速度要求。
于是乎,我需要一个可以快速开发的架构,在这个基础上,做一些基本的解耦,以方便日后项目架构升级。
3. 介绍
这是一个基于kotlin开发的轻MVP架构,开发者可以根据需求自由选择使用程度,而在需要增加层次的时候又不会有太大的改动。
基本原则是,只根据现有需求开发,不停维护迭代。
传统MVP
activity作为一个事件与生命周期的入口,作为view层不够纯粹。
同理,presenter直接隔离与activity之外,会导致冗余代码过多。
不要小看这么一两句代码,重复的劳动力操作,会让你怀疑人生!
轻MVP,不同于传统的MVP,
Model:Request、response、bean,通过Repo获取
View:新创建一个View层来控制界面显示(传统MVP把activity当成V)
control 事件入口,管理P、V,如:activity、adapter、helper...
presenter 对应于具体的界面的业务逻辑,在此使用Repo获取数据
activity 事件入口,属于control,简单的界面可以兼任presenter
viewHolder:视图句柄(kotlin有anko可以省略这个,但是目前技术尚未成熟,暂时用着先吧)
util 静态工具类,不涉及具体业务逻辑
manager 静态管理类,对于相同模块或业务逻辑的统一管理,如AppManager、UserManager、LoginManager、FooManager...
helper 辅助类,对某些特殊功能的管理,比如AnimHelper,属于control
4. 项目结构
a、app模块结构
common 项目相关工具类
entity VO、EventBus、常量表等实体
gm 全局管理,一个静态的工具类,方便对于相同模块或者业务功能做统一的处理
facade 具体业务、界面
以main为入口,home为首页,四个tab独立放一个包,其他的则另外按照模块分,这里由于app中有两个角色,所有有了aunt、customer两个区分,common则是共用的界面。
b、core模块结构
utils 工具类
base 简化操作的基类
module 具体模块的request、response、entity
repo 仓库,封装具体工具或者DAO的操作,这里将所有请求都封装成rx流操作模式
附:偶然一次发现,阿里有一个TheMVP的概念,在以activity作为presenter的想法是不谋而合,大有天下难得一知己的感慨。本文只讲述架构,如有侵权,请联系本人。
某个不要脸的居然要我在这里感谢他,那就,感谢不要脸大神ivy吧!