选型背景
首先我们的项目是学习型项目,尽可能的考虑实际生产场景中团队开发遇到的问题,并最大程度去解决存在的问题。
使用Flutter之后,普遍反馈是书写舒服,和原生相比不需要多个类的交互,在一个dart文件里,以函数式的编程,轻松布局,UI和逻辑之间的关系也更好理解。但随之而来的问题是:代码可读性差、代码可复用度低、没有统一的代码规范、UI代码业务代码耦合度高!这就非常难受了,对于团队开发而言,极大的影响开发效率,而且耦合会带来可修改性变差的问题,所以我们需要有个像MVP、MVVM那样成熟的框架帮我们规范书写格式。且Flutter有一个状态管理的问题,面对几十上百个状态,我们需要对状态进行一个同步和代码的复用,不能每个页面都写一个类文件叭!类似Model和模版页的关系。
框架选型
经过了解,主流的框架有:BLoC、Flutter-Redux、Flutter-provide、Fish-Redux。
BLoC
Business Logic Component,BLoC,由谷歌开发推出,它的思路是把UI和逻辑分离,并且UI可以分得很细,整个方案由一定的分治关系;但是逻辑是统一的,这样做的优点是逻辑和UI分离、便于测试、一定的逻辑重用。缺点是没有办法对逻辑做更进一步的分治,虽然UI可以分治,但是逻辑的不可分治问题会随着业务逻辑的增大而复杂,最终变得庞大而难以管理。
Flutter-provide
这也是谷歌推出的状态管理方案,Provider被设计为ScopedModel的替代品,并且允许我们更加灵活地处理数据类型和数据。但这种管理,只是借助了InheritWidget,将共享状态放到顶层MaterialApp之上。底层部件通过Provier获取该状态,并通过混合ChangeNotifier通知依赖于该状态的组件刷新。并没有对数据进行组织,对职责进行划分,仅仅达到状态共享的作用。适用于简单应用的状态管理。
Flutter-Redux
Flutter-Redux这个方案还是由谷歌推出的,它与前端熟知的ReactJS社区里的Redux方案几乎一致,但是基于 Dart 和 JS 语言上的差异,它没有做到把一个Reducer 变成若干个Reducer一层层分治的效果。它有唯一的一个store,直接对应下面的view,通过action的形式将数据流驱动起来,优点很明显,就是集中的数据管理、方便观察并且容易调试,并且有Middleware中间件机制更加相对容易拓展。但缺点是把数据和逻辑集中了,但是很难把这一块的东西分治出来,在庞大复杂的业务中更应该将UI和数据逻辑分离开来,不能只是将UI分治了,而逻辑还混在一起,如果这样也会导致最终项目难以维护。
Fish-Redux
Fish-Redux 是闲鱼团队基于 Redux 做的一次量身改良,通过 Redux 做集中化的可观察的数据管理。FR 是一个基于 Redux 数据管理的组装式 flutter 应用框架, 特别适用于构建中大型的复杂应用,对于传统 Redux 在使用层面上的两大缺点做了重大改良,具体做法是:首先规定一个组件需要定义一个数据(State)和一个 Reducer,同时组件之间存在着父依赖子的关系。通过这层依赖关系去解决了 集中和分治之间的矛盾,而对 Reducer 的手动层层 Combine 变成由框架自动完成,使之简化了使用 Redux 的困难,同时也得到了理想的集中的效果和分治的代码。也就是说,Fish Redux在状态管理之余,还做到了对数据的集中和逻辑的分治,支持页面级别数据池,并对代码文件做到了清晰的职责划分,有利于团队协作形成统一的代码规范。
Fish Redux 最显著的特征是函数式的编程模型、可预测的状态管理、可插拔的组件体系、最佳的性能表现。它的特点是配置式组装。一方面我们将一个大的页面,对视图和数据层层拆解为互相独立的 Component|Adapter,上层负责组装,下层负责实现;另一方面将Component|Adapter 拆分为 View,Reducer,Effect 等相互独立的上下文无关函数。优点是非常干净,易于维护,易于协作,将集中、分治、复用、隔离做的更进一步,缺点就是代码量的急剧增大(而且是非常非常非常急剧增大)。以我们项目为例,配置页面如下:
选择Fish-Redux的理由
Fish Redux是对Redux的改良,突出优点是做到了数据的集中和逻辑的分治,并支持页面级别数据池,配置式自动组装使得代码非常灵活,这是其他框架不具备的。
Fish Redux代码写起来非常干净、易维护,清晰的代码职责划分有利于团队协作代码风格统一,这种逻辑清晰、条理清楚的感觉就很舒服。
Fish Redux 还提供了一个 Adapter 的抽象组件模型,在基础的组件模型以外,Fish Redux 提供了一个 Adapter 抽象模型,用来解决在 ListView 上大 Cell 的性能问题。通过上层抽象,可以得到了逻辑上的 ScrollView,性能上的 ListView。我们项目多列表展示,最重要的组件就是ListView,Fish Redux的这个特点非常契合我们项目的需求。
-
虽然Fish Redux学习成本高,使用较为复杂,小型项目没有必要使用。但我们是一个学习型项目,知难而上是一件很有意思的事,这正是学习的意义所在。我们项目功能不复杂,对Fish Redux带来的代码量增大可以接受。
综上,我们最终选取了Fish-Redux作为我们的状态管理框架。