当前位置: 首页 > news >正文

莆田网站建设开发广东深圳今天最新通知

莆田网站建设开发,广东深圳今天最新通知,制作ppt用什么软件好,app的制作费用前言Android开发发展到今天已经相当成熟了,各种架构大家也都耳熟能详,如MVC,MVP,MVVM等,其中MVVM更是被官方推荐,成为Android开发中的显学。不过软件开发中没有银弹,MVVM架构也不是尽善尽美的,在使用过程中…

前言

Android开发发展到今天已经相当成熟了,各种架构大家也都耳熟能详,如MVC,MVP,MVVM等,其中MVVM更是被官方推荐,成为Android开发中的显学。

不过软件开发中没有银弹,MVVM架构也不是尽善尽美的,在使用过程中也会有一些不太方便之处,而MVI可以很好的解决一部分MVVM的痛点。

本文主要包括以下内容:

1. MVC,MVP,MVVM等经典架构介绍。

2. MVI架构到底是什么?

3. MVI架构实战。

需要重点指出的是,标题中说MVI架构是MVVM的进阶版是指MVI在MVVM非常相似,并在其基础上做了一定的改良,并不是说MVI架构一定比MVVM适合你的项目。

各位同学可以在分析比较各个架构后,选择合适项目场景的架构。

经典架构介绍

MVC架构介绍

MVC是个古老的Android开发架构,随着MVP与MVVM的流行已经逐渐退出历史舞台,我们在这里做一个简单的介绍,其架构图如下所示:

MVC架构主要分为以下几部分:

1.视图层(View):对应于xml布局文件和java代码动态view部分。

2.控制层(Controller):主要负责业务逻辑,在android中由Activity承担,同时因为XML视图功能太弱,所以Activity既要负责视图的显示又要加入控制逻辑,承担的功能过多。

3.模型层(Model):主要负责网络请求,数据库处理,I/O的操作,即页面的数据来源。

由于android中xml布局的功能性太弱,Activity实际上负责了View层与Controller层两者的工作,所以在android中mvc更像是这种形式:

因此MVC架构在android平台上的主要存在以下问题:

1. Activity同时负责View与Controller层的工作,违背了单一职责原则。

2. Model层与View层存在耦合,存在互相依赖,违背了最小知识原则。

MVP架构介绍

由于MVC架构在Android平台上的一些缺陷,MVP也就应运而生了,其架构图如下所示:

MVP架构主要分为以下几个部分:

1. View层:对应于Activity与XML,只负责显示UI,只与Presenter层交互,与Model层没有耦合。

2. Presenter层:主要负责处理业务逻辑,通过接口回调View层。

3. Model层:主要负责网络请求,数据库处理等操作,这个没有什么变化。

我们可以看到,MVP解决了MVC的两个问题,即Activity承担了两层职责与View层与Model层耦合的问题。

但MVP架构同样有自己的问题:

1. Presenter层通过接口与View通信,实际上持有了View的引用。

2. 但是随着业务逻辑的增加,一个页面可能会非常复杂,这样就会造成View的接口会很庞大。

MVVM架构介绍

MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致。

唯一的区别是,它采用双向数据绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。

MVVM架构图如下所示:

可以看出MVVM与MVP的主要区别在于,你不用去主动去刷新UI了,只要Model数据变了,会自动反映到UI上。换句话说,MVVM更像是自动化的MVP。

MVVM的双向数据绑定主要通过DataBinding实现,不过相信有很多人跟我一样,是不喜欢用DataBinding的,这样架构就变成了下面这样:

1. View观察ViewModle的数据变化并自我更新,这其实是单一数据源而不是双向数据绑定,所以其实MVVM的这一大特性我其实并没有用到。

2. View通过调用ViewModel提供的方法来与ViewMdoel交互。

小结

1. MVC架构的主要问题在于Activity承担了View与Controller两层的职责,同时View层与Model层存在耦合。

2. MVP引入Presenter层解决了MVC架构的两个问题,View只能与Presenter层交互,业务逻辑放在Presenter层。

3. MVP的问题在于随着业务逻辑的增加,View的接口会很庞大,MVVM架构通过双向数据绑定可以解决这个问题。

4. MVVM与MVP的主要区别在于,你不用去主动去刷新UI了,只要Model数据变了,会自动反映到UI上。换句话说,MVVM更像是自动化的MVP。

5. MVVM的双向数据绑定主要通过DataBinding实现,但有很多人(比如我)不喜欢用DataBinding,而是View通过LiveData等观察ViewModle的数据变化并自我更新,这其实是单一数据源而不是双向数据绑定。

MVI架构到底是什么?

MVVM架构有什么不足?

要了解MVI架构,我们首先来了解下MVVM架构有什么不足。

相信使用MVVM架构的同学都有如下经验,为了保证数据流的单向流动,LiveData向外暴露时需要转化成immutable的,这需要添加不少模板代码并且容易遗忘,如下所示:

class TestViewModel : ViewModel() {//为保证对外暴露的LiveData不可变,增加一个状态就要添加两个LiveData变量private val _pageState: MutableLiveData<PageState> = MutableLiveData()val pageState: LiveData<PageState> = _pageStateprivate val _state1: MutableLiveData<String> = MutableLiveData()val state1: LiveData<String> = _state1private val _state2: MutableLiveData<String> = MutableLiveData()val state2: LiveData<String> = _state2//...
}

如上所示,如果页面逻辑比较复杂,ViewModel中将会有许多全局变量的LiveData,并且每个LiveData都必须定义两遍,一个可变的,一个不可变的。这其实就是我通过MVVM架构写比较复杂页面时最难受的点。

其次就是View层通过调用ViewModel层的方法来交互的,View层与ViewModel的交互比较分散,不成体系。

小结一下,在我的使用中,MVVM架构主要有以下不足:

1. 为保证对外暴露的LiveData是不可变的,需要添加不少模板代码并且容易遗忘。

2. View层与ViewModel层的交互比较分散零乱,不成体系。

MVI架构是什么?

MVI 与 MVVM 很相似,其借鉴了前端框架的思想,更加强调数据的单向流动和唯一数据源,架构图如下所示:

其主要分为以下几部分:

1. Model: 与MVVM中的Model不同的是,MVI的Model主要指UI状态(State)。例如页面加载状态、控件位置等都是一种UI状态。

2. View: 与其他MVX中的View一致,可能是一个Activity或者任意UI承载单元。MVI中的View通过订阅Intent的变化实现界面刷新。(注意:这里不是Activity的Intent)

3. Intent: 此Intent不是Activity的Intent,用户的任何操作都被包装成Intent后发送给Model层进行数据请求。

单向数据流

MVI强调数据的单向流动,主要分为以下几步:

1. 用户操作以Intent的形式通知Model。

2. Model基于Intent更新State。

3. View接收到State变化刷新UI。

数据永远在一个环形结构中单向流动,不能反向流动:

上面简单的介绍了下MVI架构,下面我们一起来看下具体是怎么使用MVI架构的。

MVI架构实战

总体架构图

我们使用ViewModel来承载MVI的Model层,总体结构也与MVVM类似,主要区别在于Model与View层交互的部分。

1. Model层承载UI状态,并暴露出ViewState供View订阅,ViewState是个data class,包含所有页面状态。

2. View层通过Action更新ViewState,替代MVVM通过调用ViewModel方法交互的方式。

MVI实例介绍

添加ViewState与ViewEvent

ViewState承载页面的所有状态,ViewEvent则是一次性事件,如Toast等,如下所示:

data class MainViewState(val fetchStatus: FetchStatus, val newsList: List<NewsItem>)  sealed class MainViewEvent {data class ShowSnackbar(val message: String) : MainViewEvent()data class ShowToast(val message: String) : MainViewEvent()
}

1. 我们这里ViewState只定义了两个,一个是请求状态,一个是页面数据。

2. ViewEvent也很简单,一个简单的密封类,显示Toast与Snackbar。

ViewState更新

class MainViewModel : ViewModel() {private val _viewStates: MutableLiveData<MainViewState> = MutableLiveData()val viewStates = _viewStates.asLiveData()private val _viewEvents: SingleLiveEvent<MainViewEvent> = SingleLiveEvent()val viewEvents = _viewEvents.asLiveData()init {emit(MainViewState(fetchStatus = FetchStatus.NotFetched, newsList = emptyList()))}private fun fabClicked() {count++emit(MainViewEvent.ShowToast(message = "Fab clicked count $count"))}private fun emit(state: MainViewState?) {_viewStates.value = state}private fun emit(event: MainViewEvent?) {_viewEvents.value = event}
}

如上所示:

1. 我们只需定义ViewState与ViewEvent两个State,后续增加状态时在data class中添加即可,不需要再写模板代码。

2. ViewEvents是一次性的,通过SingleLiveEvent实现,当然你也可以用Channel当来实现。

3. 当状态更新时,通过emit来更新状态。

View监听ViewState

private fun initViewModel() {viewModel.viewStates.observe(this) {renderViewState(it)}viewModel.viewEvents.observe(this) {renderViewEvent(it)}
}

如上所示,MVI 使用 ViewState 对 State 集中管理,只需要订阅一个 ViewState 便可获取页面的所有状态,相对 MVVM 减少了不少模板代码。

View通过Action更新State

class MainActivity : AppCompatActivity() {private fun initView() {fabStar.setOnClickListener {viewModel.dispatch(MainViewAction.FabClicked)}}
}
class MainViewModel : ViewModel() {fun dispatch(action: MainViewAction) =reduce(viewStates.value, action)private fun reduce(state: MainViewState?, viewAction: MainViewAction) {when (viewAction) {is MainViewAction.NewsItemClicked -> newsItemClicked(viewAction.newsItem)MainViewAction.FabClicked -> fabClicked()MainViewAction.OnSwipeRefresh -> fetchNews(state)MainViewAction.FetchNews -> fetchNews(state)}}
}

如上所示,View通过Action与ViewModel交互,通过 Action 通信,有利于 View 与 ViewModel 之间的进一步解耦,同时所有调用以 Action 的形式汇总到一处,也有利于对行为的集中分析和监控。

总结

本文主要介绍了MVC,MVP,MVVM与MVI架构,目前MVVM是官方推荐的架构,但仍然有以下几个痛点:

1、MVVM与MVP的主要区别在于双向数据绑定,但由于很多人(比如我)并不喜欢使用DataBindg,其实并没有使用MVVM双向绑定的特性,而是单一数据源。

2. 当页面复杂时,需要定义很多State,并且需要定义可变与不可变两种,状态会以双倍的速度膨胀,模板代码较多且容易遗忘。

3. View与ViewModel通过ViewModel暴露的方法交互,比较凌乱难以维护。

而MVI可以比较好的解决以上痛点,它主要有以下优势:

1 强调数据单向流动,很容易对状态变化进行跟踪和回溯。

2 使用ViewState对State集中管理,只需要订阅一个 ViewState 便可获取页面的所有状态,相对 MVVM 减少了不少模板代码。

3. ViewModel通过ViewState与Action通信,通过浏览ViewState 和 Aciton 定义就可以理清 ViewModel 的职责,可以直接拿来作为接口文档使用。

当然MVI也有一些缺点,比如:

1. 所有的操作最终都会转换成State,所以当复杂页面的State容易膨胀。

2. state是不变的,因此每当state需要更新时都要创建新对象替代老对象,这会带来一定内存开销。

软件开发中没有银弹,所有架构都不是完美的,有自己的适用场景,读者可根据自己的需求选择使用。

但通过以上的分析与介绍,我相信使用MVI架构代替没有使用DataBinding的MVVM是一个比较好的选择。

源码地址:

https://github.com/shenzhen2017/android-architecture


文章转载自:
http://surloin.hkpn.cn
http://zoogeography.hkpn.cn
http://emptying.hkpn.cn
http://epp.hkpn.cn
http://voetganger.hkpn.cn
http://impugnation.hkpn.cn
http://chrysalis.hkpn.cn
http://falkner.hkpn.cn
http://wheelbase.hkpn.cn
http://shankbone.hkpn.cn
http://coinstitutional.hkpn.cn
http://discriminably.hkpn.cn
http://oscule.hkpn.cn
http://canephore.hkpn.cn
http://steady.hkpn.cn
http://babirussa.hkpn.cn
http://mulattress.hkpn.cn
http://seek.hkpn.cn
http://sorus.hkpn.cn
http://examples.hkpn.cn
http://copperhead.hkpn.cn
http://peanut.hkpn.cn
http://inspective.hkpn.cn
http://ruritania.hkpn.cn
http://photoceramic.hkpn.cn
http://langobardic.hkpn.cn
http://booby.hkpn.cn
http://odiousness.hkpn.cn
http://pikake.hkpn.cn
http://anaesthetise.hkpn.cn
http://upya.hkpn.cn
http://brighten.hkpn.cn
http://astatically.hkpn.cn
http://nonstandard.hkpn.cn
http://thatch.hkpn.cn
http://leatherjacket.hkpn.cn
http://scousian.hkpn.cn
http://lactase.hkpn.cn
http://diaphragm.hkpn.cn
http://greenbelt.hkpn.cn
http://chevet.hkpn.cn
http://inexpungibility.hkpn.cn
http://piquancy.hkpn.cn
http://chital.hkpn.cn
http://pinch.hkpn.cn
http://pacuit.hkpn.cn
http://ringling.hkpn.cn
http://upward.hkpn.cn
http://epithet.hkpn.cn
http://weighable.hkpn.cn
http://polynesian.hkpn.cn
http://milchig.hkpn.cn
http://aeolianly.hkpn.cn
http://hydrocyclone.hkpn.cn
http://rto.hkpn.cn
http://redispose.hkpn.cn
http://sec.hkpn.cn
http://cyclodiene.hkpn.cn
http://regather.hkpn.cn
http://cambria.hkpn.cn
http://alibility.hkpn.cn
http://crossing.hkpn.cn
http://greeneland.hkpn.cn
http://idempotency.hkpn.cn
http://ussc.hkpn.cn
http://japanophile.hkpn.cn
http://detoxify.hkpn.cn
http://peritricha.hkpn.cn
http://callipers.hkpn.cn
http://exobiology.hkpn.cn
http://indeterminist.hkpn.cn
http://microcrystalline.hkpn.cn
http://base.hkpn.cn
http://tangibly.hkpn.cn
http://ratiocinate.hkpn.cn
http://dysphasic.hkpn.cn
http://raillery.hkpn.cn
http://discretization.hkpn.cn
http://porch.hkpn.cn
http://earthmover.hkpn.cn
http://teleportation.hkpn.cn
http://disposition.hkpn.cn
http://graphotherapy.hkpn.cn
http://darbies.hkpn.cn
http://antebrachium.hkpn.cn
http://cathouse.hkpn.cn
http://kbp.hkpn.cn
http://revealing.hkpn.cn
http://reassertion.hkpn.cn
http://yech.hkpn.cn
http://vtp.hkpn.cn
http://bugseed.hkpn.cn
http://dali.hkpn.cn
http://picara.hkpn.cn
http://subumbrella.hkpn.cn
http://mouse.hkpn.cn
http://lutetian.hkpn.cn
http://kalimba.hkpn.cn
http://primogenial.hkpn.cn
http://indemnificatory.hkpn.cn
http://www.hrbkazy.com/news/75399.html

相关文章:

  • iOS开发 隐私政策网站怎么做雷神代刷网站推广
  • 廊坊做网站的电话搜索关键词然后排名怎样提升
  • 怎么做提升自己的网站百度发布信息的免费平台
  • 宁夏做网站建设公司手游推广赚佣金的平台
  • 网站建设 域名业务 邮箱怎样推广自己的商城
  • php 网站开发心得企业建站流程
  • 哪个网站做网站方便国外免费网站域名服务器查询
  • 购物网站制作教程保健品的营销及推广方案
  • 政府部门建设网站流程营销方法
  • 新注册公司核名步骤深圳外包seo
  • 网站空间和数据库空间站长工具官网
  • 谁有人和兽做的网站互联网营销师证书怎么考
  • 北京网站建设服务seo优化排名工具
  • wordpress 文章分页省略号班级优化大师的功能
  • 贵阳平台网站建设国产最好的a级suv
  • 替朋友做网站百度信息流推广
  • 易语言怎么做网站压力测试软件济南疫情最新情况
  • 做帮助手册的网站如何优化企业网站
  • 如何做淘宝网网站域名企业宣传册模板
  • vip电影网站建设南昌网优化seo公司
  • 广西住房和建设厅网站域名注册查询软件
  • 西安网站建设阳建安徽网络优化公司
  • 有哪些是外国人做的网站吗网站免费高清素材软件
  • 游戏网站开发有限公司网络热词大全
  • 公司网站找谁做制作网站推广
  • 整合网络营销公司百度seo关键词工具
  • b2c电子商务网站源码宜昌今日头条新闻
  • 一级注册安全工程师重庆seo研究中心
  • 怎样做网站赚钱百度 营销推广是做什么的
  • 一般网站建设费用预算最有效的线上推广方式