基于GetX的Flutter项目架构设计方案

  • 发表于
  • flutter

前言

本文探讨的是一种基于Flutter进行全新App项目的开发模式,不涉及老的代码复用等问题。

关于在现有Android或iOS项目中接入flutter框架,这属于混合栈开发的内容,可以参考阿里巴巴的flutter boost的方案,或者企业微信的FlutterThrio方案。

本文假设读者已经基本熟悉Flutter的开发,并对主流的Flutter状态管理方案(Redux, Bloc, Provider等)有一定的了解。

GetX介绍

GetX 是 Flutter 上的一个轻量且强大的解决方案:高性能的状态管理、智能的依赖注入和便捷的路由管理。

GetX 有3个基本原则:

  • 性能: GetX 专注于性能和最小资源消耗。GetX 打包后的apk占用大小和运行时的内存占用与其他状态管理插件不相上下。如果你感兴趣,这里有一个性能测试。
  • 效率: GetX 的语法非常简捷,并保持了极高的性能,能极大缩短你的开发时长。
  • 结构: GetX 可以将界面、逻辑、依赖和路由完全解耦,用起来更清爽,逻辑更清晰,代码更容易维护。

GetX 并不臃肿,却很轻量。如果你只使用状态管理,只有状态管理模块会被编译,其他没用到的东西都不会被编译到你的代码中。它拥有众多的功能,但这些功能都在独立的容器中,只有在使用后才会启动。

Getx有一个庞大的生态系统,能够在Android、iOS、Web、Mac、Linux、Windows和你的服务器上用同样的代码运行。 通过Get Server 可以在你的后端完全重用你在前端写的代码。

为什么选择GetX

每个App开发者都听说过 "将界面与业务逻辑分离 "的概念,这并不是BLoC、MVC、MVVM的特有的,市面上的其他标准都有这个概念。

由于使用了上下文(context),这个概念在Flutter中往往可以得到缓解。如果你需要上下文来寻找InheritedWidget,你需要在界面中找到它,或者通过参数传递上下文。

我特别觉得这种解决方案非常丑陋,在团队中我们总会对View的业务逻辑产生依赖。GetX与标准的做法不一样,虽然它并没有完全禁止使用StatefulWidgets、InitState等,但它总有类似的方法,可以更干净。

控制器是有生命周期的,例如当你需要进行API请求时,你不依赖于界面中的任何东西。你可以使用onInit来启动http调用,当数据到达时,变量将被填充。由于GetX是完全响应式的,一旦项目被填充,所有使用该变量的widgets将在界面中自动更新。这使得具有UI专业知识的人只需要处理widget,除了用户事件(比如点击按钮)之外,不需要向业务逻辑发送任何东西,而处理业务逻辑的人将可以自由地单独创建和测试业务逻辑。

主要功能

App开发有三大功能:状态管理、路由管理、依赖管理,GetX都有对应的解决方案,还有多语言、主题切换等。

状态管理

目前,Flutter有几种状态管理器。但是,它们中的大多数都涉及到使用ChangeNotifier来更新widget,这对于中大型应用的性能来说是一个很糟糕的方法。你可以在Flutter的官方文档中查看到,ChangeNotifier应该使用1个或最多2个监听器,这使得它们实际上无法用于任何中等或大型应用。

Get 并不是比任何其他状态管理器更好或更差,而是说你应该分析这些要点以及下面的要点来选择只用Get,还是与其他状态管理器结合使用。

Get有两个不同的状态管理器:简单的状态管理器(GetBuilder)和响应式状态管理器(GetX)。

响应式状态管理器

响应式编程可能会让很多人感到陌生,因为觉得它很复杂,但是GetX将响应式编程变得非常简单。

  • 你不需要创建StreamControllers.
  • 你不需要为每个变量创建一个StreamBuilder。
  • 你不需要为每个状态创建一个类。
  • 你不需要为一个初始值创建一个get。

让我们想象一下,你有一个名称变量,并且希望每次你改变它时,所有使用它的小组件都会自动刷新。
这就是你的计数变量。

要想让它变得可观察,你只需要在它的末尾加上".obs"。

而在UI中,当你想显示该值并在值变化时更新页面,只需这样做。

这就是全部,就这么简单。

路由管理

导航到新页面

返回前一个页面:

依赖管理

Get有一个简单而强大的依赖管理器,它允许你只用1行代码就能检索到与你的Bloc或Controller相同的类,无需Provider context,无需inheritedWidget。

  • 注意:如果你使用的是Get的状态管理器,请多注意绑定api,这将使你的界面更容易连接到你的控制器。

你是在Get实例中实例化它,而不是在你使用的类中实例化你的类,这将使它在整个App中可用。
所以你可以正常使用你的控制器(或类Bloc)。

提示: Get依赖管理与包的其他部分是解耦的,所以如果你的应用已经使用了一个状态管理器(任何一个,都没关系),你不需要全部重写,你可以使用这个依赖注入。

想象一下,你已经浏览了无数条路由,现在你需要拿到一个被遗留在控制器中的数据,那你需要一个状态管理器与Provider或Get_it一起使用来拿到它,对吗?用Get则不然,Get会自动为你的控制器找到你想要的数据,而你甚至不需要任何额外的依赖关系。

然后你就可以恢复你在后面获得的控制器数据。

项目结构

分层架构

按照传统分层方式划分,如下图:

基于GetX的Flutter项目架构设计方案

主要分为四个层次

  • 页面层:即业务逻辑
  • 组件层:每个页面通用的功能组件
  • 服务层:不依赖于业务的核心功能模块
  • 框架层:即Flutter的两个UI框架

数据流程

基于GetX的Flutter项目架构设计方案

Data的来源有两个:

  • Cache 本地缓存直接读取
  • Repository-Provider 网络数据

页面内的数据流转

页面代码拆分也是MVC和响应式的设计思想,拆分成Controller、View、State。

基于GetX的Flutter项目架构设计方案

总结

综上所述,此架构模式基本上可以做到模板化,有充分的解耦性和扩展性,但又不会增加太多复杂性,尤其适合在中小型App中应用。

架构的目的就是为了解决复杂性

当你的项目团队只有几个人的情况下,过度关注组件化、代码隔离会让团队的心智负担飙升,过于分工并不能带来很好的效果。每一种架构最终都是一个平衡的结果,一定要结合团队实际情况进行取舍,不能一味的追求高大上。