尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

深入 Mango 源码:MVP 架构如何优雅组织 6 大业务模块(Contract/Presenter 实战解析)

深入 Mango 源码:MVP 架构如何优雅组织 6 大业务模块(Contract/Presenter 实战解析) 深入 Mango 源码MVP 架构如何优雅组织 6 大业务模块Contract/Presenter 实战解析【免费下载链接】Mango An Android app for dribbble.com项目地址: https://gitcode.com/gh_mirrors/mango13/MangoMango 是一个专为 dribbble.com 打造的开源 Android 客户端代码量适中、结构清晰是学习MVP 架构与Contract/Presenter 组织方式的绝佳样本。很多初学者写 Android 项目时最头疼的问题就是业务一多代码就乱而 Mango 用一套近乎统一的范式把认证、主界面、作品流、作品详情、用户主页、设置这 6 大业务模块打理得井井有条。本文将带你逐模块拆解它的源码看透一个模块三个文件的优雅组织艺术。Mango 项目速览一个 Dribbble 客户端为何要选 MVPMVPModel-View-Presenter把界面逻辑从 View 中剥离交给 Presenter 统一处理。Mango 的诉求很典型页面多、每个页面都有网络请求、都有加载态与错误态。如果全塞进 Activity/Fragment文件动辄上千行且难以复用。Mango 的做法是每个页面固定由三个文件组成全部位于app/src/main/java/io/github/tonnyl/mango/ui/目录下XxxContract.kt定义 View 与 Presenter 之间的契约XxxPresenter.kt实现全部业务逻辑只面向接口编程XxxFragment.kt/XxxActivity.kt只负责渲染与事件转发这种结构让每个文件职责单一新人接手时看一眼 Contract 就能理解整个页面的交互全貌。MVP 架构的三层协议BaseView 与 BasePresenter 如何约束全局Mango 在app/src/main/java/io/github/tonnyl/mango/mvp/下定义了两个全局基接口所有模块都继承它们。先看 BasePresenter.kt它只有两个方法interface BasePresenter { fun subscribe() // 页面可见时订阅数据 fun unsubscribe() // 页面销毁时释放资源 }再看 BaseView.kt它用泛型强制建立View 必须持有 Presenter的约束interface BaseViewin T { fun setPresenter(presenter: T) }这套设计非常精妙生命周期与资源回收被抽象成统一协议每个 Presenter 在init块里调用mView.setPresenter(this)完成双向绑定。所谓架构很多时候就是把约定上升为接口约束。一个模块三个文件Contract 接口如何锁死View 与 Presenter 的契约Contract 是 Mango 架构的灵魂文件。它内部嵌套两个接口相当于一份页面级需求文档interface MainContract { interface View : BaseViewPresenter { fun initViews() fun showAuthUserInfo(user: User) fun disableShortcuts() fun navigateToLogin() } interface Presenter : BasePresenter { fun fetchUser() fun logoutUser() fun getUser(): User? } }以上是 MainContract.kt 的真实代码。可以看到View 接口声明界面能展示什么Presenter 接口声明业务能做什么二者通过泛型BaseViewPresenter互相引用谁也不能越界。改需求先改 Contract编译错误会立刻告诉你哪些实现方需要同步修改——这就是契约的力量。6 大业务模块逐一拆解MVP 架构的实战范例Mango 的 6 大业务模块覆盖了一个社交类应用的完整闭环每个都是可复制的模板。模块一Auth 认证模块——登录流程的 MVP 实战AuthContract.kt 是 MVP 架构中最典型的登录页案例。View 侧定义了setLoginIndicator加载转圈、showMessage错误提示、updateLoginStatus登录成功回填 TokenPresenter 侧只有一个核心方法requestAccessToken(code: String)负责拿 OAuth 授权码换令牌。这里值得注意的细节是View 接口刻意暴露isActive()判断页面是否存活防止异步回调打到已销毁的界面上——这是处理网络回调竞态的经典防护。模块二Main 主界面模块——聚合用户信息与快捷键主界面负责拉取登录用户信息、管理桌面快捷键shortcuts其 Presenter 实现 MainPresenter.kt 是理解Presenter 如何驱动 View的最佳入口。核心方法fetchUser()展示了标准的数据流override fun fetchUser() { val disposable AuthUserRepository.getAuthenticatedUser(AccessTokenManager.accessToken?.id) .subscribeOn(Schedulers.io()) // 网络请求放 IO 线程 .observeOn(AndroidSchedulers.mainThread()) // 回到主线程更新 UI .subscribe({ response - mUser response mView.showAuthUserInfo(response) // 只调接口不碰具体 View }) mCompositeDisposable.add(disposable) // 统一登记订阅 }Presenter 全程不知道界面是 Fragment 还是 Activity它只认MainContract.View接口——这就是可测试性的来源。模块三Shots 列表模块——分页加载的经典范式作品流是 Dribbble 客户端的主战场。ShotsPageContract.kt 中 View 声明了showResults、notifyDataAdded、showNetworkError、setEmptyContentVisibility等一整套列表状态接口Presenter 则只暴露listShots()与listMoreShots()两个方法。把首次加载与加载更多拆成两个独立方法让下拉刷新、上拉分页的职责一目了然配合setLoadingIndicator控制转圈动画一个健壮的列表页就搭好了。模块四Shot 详情模块——点赞、评论、分享的交互枢纽ShotContract.kt 是 Mango 里方法最多的契约View 要展示点赞状态、更新点赞数、跳转用户主页、跳转评论、跳转点赞列表、浏览器打开、分享……Presenter 与之逐一对应。有趣的是跳转逻辑也被收进 ContractView 声明navigateToComments(shot: Shot)Presenter 声明navigateToComments()。谁负责跳转由实现方决定契约只保证这个动作一定会发生。模块五User 用户主页模块——关注关系的状态机UserProfileContract.kt 展示了一个有趣的抽象View 用setFollowing(isFollowing: Boolean)和setFollowable(followable: Boolean)两个方法就把关注/取关的复杂状态机收敛成了两个布尔值。Presenter 只需在toggleFollow()成功后回调更新即可。这种把状态抽象成简单接口把复杂逻辑留在 Presenter的思路非常值得在小而美的业务场景中借鉴。模块六Settings 设置模块——缓存管理的最小实现SettingsContract.kt 是全场最精简的模块View 只有updateCacheSize(size: Long)Presenter 只有computeCacheSize和clearCache。两个方法就把显示缓存大小 清理缓存这个业务闭环描述完毕。即便是这种轻量页面Mango 也严格遵循同一套三件套结构用一致性换可维护性这正是架构的意义所在。Presenter 的三个实战技巧线程调度、订阅管理与生命周期绑定从 MainPresenter.kt 可以提炼出三个写 Presenter 的黄金法则IO/主线程显式调度所有网络请求subscribeOn(Schedulers.io())所有 UI 更新observeOn(AndroidSchedulers.mainThread())绝不把线程切换散落在 View 里。CompositeDisposable 统一管理订阅每个 Presenter 持有CompositeDisposable每次请求都add()进去unsubscribe()时一次clear()从根上杜绝内存泄漏。生命周期钩子对齐在onStart/onResume调subscribe()在onStop/onDestroy调unsubscribe()让 MVP 的绑定关系与页面生命周期严格同步。总结从 Mango 学到的最优 MVP 架构组织经验回看 Mango 的 6 大业务模块你会惊讶于它们的高度同构一样的三个文件、一样的 BasePresenter 生命周期、一样的 RxJava 线程三板斧。这种约定优于配置的组织方式让一个十几人甚至单人维护的开源项目依然能长期保持代码整洁。如果你正在设计自己的 Android 项目架构不妨直接复制 Mango 的这套模式先写 Contract 定契约再写 Presenter 管业务最后让 Fragment 只做哑视图。当你需要把项目从 6 个模块扩展到 60 个模块时就会明白这份优雅有多么重要。想要上手阅读完整源码克隆仓库地址为https://gitcode.com/gh_mirrors/mango13/Mango从ui/目录开始你的 MVP 架构之旅吧 【免费下载链接】Mango An Android app for dribbble.com项目地址: https://gitcode.com/gh_mirrors/mango13/Mango创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表