3月5日,闲鱼宣布在GitHub上开源Fish Redux,Fish Redux是一个基于 Redux 数据管理的组装式 flutter 应用框架, 特别适用于构建中大型的复杂应用,它最显著的特征是 函数式的编程模型、可预测的状态管理、可插拔的组件体系、最佳的性能表现。下文中,咱们将详细介绍Fish Redux的特色和使用过程,如下内容来自InfoQ独家对闲鱼Flutter团队的采访和Fish Redux的开源文档。前端
在闲鱼接入Flutter之初,因为咱们的落地的方案但愿是从最复杂的几个主链路进行尝试来验证flutter完备性的,而咱们的详情总体来说业务比较复杂,主要体如今两个方面:git
在咱们尝试使用市面上已有的框架(google提供的redux以及bloc)的时候发现,没有任何一个框架能够既解决集中状态管理,又能解决UI的组件化的,由于自己这两个问题有必定的矛盾性(集中vs分治)。所以咱们但愿有一套框架能解决咱们的问题,fish redux应运而生。程序员
fish redux自己是通过比较屡次的迭代的,目前你们看到的版本通过了3次比较大的迭代,实际上也是通过了团队比较多的讨论和思考。github
第一个版本是基于社区内的flutter_redux进行的改造,核心是提供了UI代码的组件化,固然问题也很是明显,针对复杂的详情和发布业务,每每业务逻辑不少,没法作到逻辑代码的组件化。编程
第二个版本针对第一个版本的问题,作出了比较重大的修改,解决了UI代码和逻辑代码的分治问题,但同时,按照redux的标准,打破了redux的原则,对于精益求精的闲鱼团队来说,不能接受;redux
所以,在第三个版本进行重构时,咱们确立了总体的架构原则与分层要求,一方面按照reduxjs的代码进行了flutter侧的redux实现,将redux的原则完整保留下来。另外一方面针对组件化的问题,提供了redux之上的component的封装,并创新的经过这一层的架构设计提供了业务代码分治的能力。性能优化
至此,咱们完成了fish redux的基本设计,但在后续的应用中,发现了业务组装之后的代码性能问题,针对该问题,咱们再次提供了对应的adapter能力,保障了在长列表场景下的big cell问题。目前,fish redux已经在线上稳定运行超过3个月以上,将来,期待fish redux给社区带来更多的输入。架构
分层架构图app
架构图:主体自底而上,分两层,每一层用来解决不通层面的问题和矛盾,下面依次来展开。框架
Redux 是来自前端社区的一个数据管理框架,对 Native开发同窗来讲可能会有一点陌生,咱们作一个简单的介绍。
Redux 是作什么的?
Redux 是一个用来作可预测易调试的数据管理的框架。全部对数据的增删改查等操做都由 Redux 来集中负责。
Redux 是怎么设计和实现的?
Redux 是一个函数式的数据管理的框架。传统 OOP 作数据管理,每每是定义一些 Bean,每个 Bean 对外暴露一些 Public-API 用来操做内部数据(充血模型)。
函数式的作法是更上一个抽象的纬度,对数据的定义是一些 Struct(贫血模型),而操做数据的方法都统一到具备相同函数签名 (T, Action) => T 的 Reducer 中。
FP:Struct(贫血模型) + Reducer = OOP:Bean(充血模型)
同时 Redux 加上了 FP 中经常使用的 Middleware(AOP) 模式和 Subscribe 机制,给框架带了极高的灵活性和扩展性。
贫血模型、充血模型请参考:
https://en.wikipedia.org/wiki/Plain_old_Java_object
Redux 的缺点
Redux 核心仅仅关心数据管理,不关心具体什么场景来使用它,这是它的优势同时也是它的缺点。
在咱们实际使用 Redux 中面临两个具体问题:
Fish Redux 经过 Redux 作集中化的可观察的数据管理。然不只于此,对于传统 Redux 在使用层面上的缺点,在面向端侧 flutter 页面纬度开发的场景中,咱们经过更好更高的抽象,作了改良。
一个组件须要定义一个数据(Struct)和一个 Reducer。同时组件之间存在着父依赖子的关系。经过这层依赖关系,
咱们解决了【集中】和【分治】之间的矛盾,同时对 Reducer 的手动层层 Combine 变成由框架自动完成,大大简化了使用 Redux 的困难。
咱们获得了理想的集中的效果和分治的代码。
State、Action、Reducer、Store、Middleware 以上概念和社区的 ReduxJS 是彻底一致的。咱们将原汁原味地保留全部的 Redux 的优点。
若是想对 Redux 有更近一步的理解,请参考:https://github.com/reduxjs/redux
组件是对局部的展现和功能的封装。 基于 Redux 的原则,咱们对功能细分为修改数据的功能(Reducer)和非修改数据的功能(反作用 Effect)。
因而咱们获得了,View、 Effect、Reducer 三部分,称之为组件的三要素,分别负责了组件的展现、非修改数据的行为、修改数据的行为。
这是一种面向当下,也面向将来的拆分。在面向当下的 Redux 看来,是数据管理和其余。在面向将来的 UI-Automation 看来是 UI 表达和其余。
UI 的表达对程序员而言即将进入黑盒时代,研发工程师们会把更多的精力放在非修改数据的行为、修改数据的行为上。
组件是对视图的分治,也是对数据的分治。经过逐层分治,咱们将复杂的页面和数据切分为相互独立的小模块。这将利于团队内的协做开发。
View 仅仅是一个函数签名: (T,Dispatch,ViewService) => Widget
它主要包含三方面的信息
Effect 是对非修改数据行为的标准定义,它是一个函数签名: (Context, Action) => Object
它主要包含四方面的信息
好比良好的协程的支持:
Reducer 是一个彻底符合 Redux 规范的函数签名:(T,Action) => T
一些符合签名的 Reducer:
同时咱们以显式配置的方式来完成大组件所依赖的小组件、适配器的注册,这份依赖配置称之为 Dependencies。
因此有这样的公式 Component = View + Effect(可选) + Reducer(可选) + Dependencies(可选)。
一个典型的组装:
经过 Component 的抽象,咱们获得了完整的分治,多纬度的复用,更好的解耦。
Adapter 也是对局部的展现和功能的封装。它为 ListView 高性能场景而生,它是 Component 实现上的一种变化。
它的目标是解决 Component 模型在 flutter-ListView 的场景下的 3 个问题:
1)将一个"Big-Cell"放在 Component 里,没法享受 ListView 代码的性能优化;
2)Component 没法区分 appear|disappear 和 init|dispose ;
3)Effect 的生命周期和 View 的耦合,在 ListView 的场景下不符合直观的预期。
归纳的讲,咱们想要一个逻辑上的 ScrollView,性能上的 ListView ,这样的一种局部展现和功能封装的抽象。作出这样独立一层的抽象是咱们看实际的效果,咱们对页面不使用框架Component,使用框架 Component+Adapter 的性能基线对比。
咱们经过不断的测试作对比,以某 Android机为例:
推荐的目录结构会是这样
sample_page -- action.dart -- page.dart -- view.dart -- effect.dart -- reducer.dart -- state.dart components sample_component -- action.dart -- component.dart -- view.dart -- effect.dart -- reducer.dart -- state.dart
上层负责组装,下层负责实现, 同时会有一个插件提供, 便于咱们快速填写。
以闲鱼的详情场景为例的组装:
组件和组件之间,组件和容器之间都彻底的独立。
简单的描述:采用的是带有一段优先处理的广播, self-first-broadcast。
发出的 Action,本身优先处理,不然广播给其余组件和 Redux 处理。最终咱们经过一个简单而直观的 dispatch 完成了组件内,组件间(父到子,子到父,兄弟间等)的全部的通讯诉求。
数据刷新
层层的数据的拷贝:
视图刷新
扁平化通知到全部组件,组件经过 shouldUpdate 肯定本身是否须要刷新。
数据的集中管理
经过 Redux 作集中化的可观察的数据管理。咱们将原汁原味地保留全部的 Redux 的优点,同时在 Reducer 的合并上,变成由框架代理自动完成,大大简化了使用 Redux 的繁琐度。
组件的分治管理
组件既是对视图的分治,也是对数据的分治。经过逐层分治,咱们将复杂的页面和数据切分为相互独立的小模块。这将利于团队内的协做开发。
View、Reducer、Effect 隔离
将组件拆分红三个无状态的互不依赖的函数。由于是无状态的函数,它更易于编写、调试、测试、维护。同时它带来了更多的组合、复用和创新的可能。
声明式配置组装
组件、适配器经过自由的声明式配置组装来完成。包括它的 View、Reducer、Effect 以及它所依赖的子项。
良好的扩展性
核心框架保持本身的核心的三层关注点,不作核心关注点之外的事情,同时对上层保持了灵活的扩展性。
精小、简单、完备
开源以后,闲鱼打算经过如下方式来维护Fish Redux:
Fish Redux 目前已在阿里巴巴闲鱼技术团队内多场景,深刻应用。最后 Talk is cheap, Show me the code,咱们今天正式在GitHub上开源,更多内容,请到GitHub了解。
GitHub地址:https://github.com/alibaba/fish-redux
本文为云栖社区原创内容,未经容许不得转载。