前言:
本文将讨论一种全新的基于Flutter开发 App 项目的模式,不涉及旧代码的复用等问题。
关于在现有的 Android 或 iOS 项目中集成 Flutter 框架,这属于混合栈开发的内容。可以参考阿里巴巴的 Flutter Boost 方案或企业微信的 FlutterThrio 方案。
本文假设读者已经基本熟悉 Flutter 开发,并对主流的 Flutter 状态管理方案(如 Redux、Bloc、Provider 等)有一定了解。
GetX 是 Flutter 上一款强大且轻量的解决方案,提供高性能的状态管理、智能的依赖注入和便捷的路由管理。
GetX 的核心原则包括:
1. 性能:GetX 专注于性能和资源消耗的最小化。打包后的 APK 大小和运行时内存占用与其他状态管理插件相当。如果你感兴趣,可以进行性能测试。
2. 效率:GetX 的语法简洁高效,能够大大缩短开发时间。
3. 结构:GetX 可以将界面、逻辑、依赖和路由完全解耦,使代码更清晰易于维护。
GetX 并不臃肿,而是非常轻量。如果只使用状态管理功能,只有状态管理模块会被编译,其他未使用的功能不会被包含在代码中。它拥有众多功能,但这些功能都在独立的容器中,只有在使用时才会启动。
为什么选择 GetX
每个 App 开发者都熟悉”将界面与业务逻辑分离”的概念,这并不是 BLoC、MVC、MVVM 等特有的,其他标准也都有类似的概念。
在 Flutter 中,由于使用了上下文(context),这个概念往往可以得到缓解。如果你需要上下文来寻找 InheritedWidget,你需要在界面中找到它,或者通过参数传递上下文。
然而,我个人认为这种解决方案非常丑陋。在团队中,我们经常会对 View 的业务逻辑产生依赖。而 GetX 与传统的做法不同,它虽然没有完全禁止使用 StatefulWidgets、InitState 等,但提供了类似的方法,使得代码更加整洁。
在 GetX 中,控制器具有生命周期。例如,当你需要进行 API 请求时,你不需要依赖界面中的任何东西。你可以使用 onInit 方法来启动 http 调用,当数据到达时,变量将被填充。由于 GetX 是完全响应式的,一旦数据被填充,所有使用该变量的 widgets 将自动更新。这使得具有 UI 专业知识的人只需要处理 widget,除了用户事件(比如点击按钮)之外,不需要向业务逻辑发送任何东西。而处理业务逻辑的人则可以自由地单独创建和测试业务逻辑。
主要功能
App 开发有三大功能:状态管理、路由管理、依赖管理,GetX 都有对应的解决方案,还有多语言、主题切换等。
状态管理
目前,Flutter 提供了几种状态管理器。然而,大多数状态管理器都使用 ChangeNotifier 来更新 widget,这对于中大型应用的性能来说并不理想。根据 Flutter 官方文档的建议,ChangeNotifier 应该只用于 1 个或最多 2 个监听器,因此在中等或大型应用中实际上无法使用。
Get 并不是比其他状态管理器更好或更差,而是根据以下要点来选择是否只使用 Get 或与其他状态管理器结合使用。
Get 提供了两种不同的状态管理器:简单的状态管理器(GetBuilder)和响应式状态管理器(GetX)。
响应式状态管理器
响应式编程可能对许多人来说比较陌生,因为它看起来很复杂。然而,GetX 使得响应式编程变得非常简单。
使用 GetX,你无需创建 StreamControllers。
使用 GetX,你无需为每个变量创建一个 StreamBuilder。
使用 GetX,你无需为每个状态创建一个类。
使用 GetX,你无需为初始值创建一个 get 方法。
让我们假设你有一个名称变量,并且希望每次该变量发生变化时,所有使用它的小组件都会自动刷新。这就是你需要的计数变量。
// https://www.huizhanii.com
var name = 'Jack';
要想让它变得可观察,你只需要在它的末尾加上”.obs”。
// https://www.huizhanii.com
var name = 'Jack'.obs;
而在 UI 中,当你想显示该值并在值变化时更新页面,只需这样做。
// https://www.huizhanii.com
Obx(() => Text("${controller.name}"));
这就是全部,就这么简单。
路由管理
导航到新页面
// https://www.huizhanii.com
Get.to(NextScreen()); // class 方式
Get.toNamed('/details');// URL 方式
返回前一个页面:
// https://www.huizhanii.com
Get.back(); // 退出或关闭
Get.off(NextScreen()); // 进入下一个页面,但没有返回上一个页面的选项(用于闪屏页,登录页面等)
Get.offAll(NextScreen()); // 进入下一个页面并取消之前的所有路由(在购物车、投票和测试中很有用)
依赖管理
Get 有一个简单而强大的依赖管理器,它允许你只用 1 行代码就能检索到与你的 Bloc 或 Controller 相同的类,无需 Provider context,无需 inheritedWidget。
// https://www.huizhanii.com
Controller controller = Get.put(Controller()); // 而不是 Controller controller = Controller();
注意:如果你使用的是 Get 的状态管理器,请特别注意绑定api,这样可以更轻松地将你的界面连接到控制器。
在 Get 实例中实例化它,而不是在你使用的类中实例化你的类,这样它就可以在整个应用程序中使用。
因此,你可以正常使用你的控制器(或类 Bloc)。
提示:Get 的依赖管理与包的其他部分是解耦的,因此如果你的应用程序已经使用了其他状态管理器(无论是哪个),你不需要完全重写它,你可以使用这个依赖注入。
// https://www.huizhanii.com
controller.fetchApi();
想象一下,你已经浏览了许多路由,现在你需要获取控制器中遗留的数据,那么你需要使用一个状态管理器,例如 Provider 或 Get_it,来获取它,对吗?但是使用 Get 就不同了,Get 会自动为你的控制器找到你想要的数据,而且你甚至不需要任何额外的依赖关系。
// https://www.huizhanii.com
Controller controller = Get.find();
//是的,它看起来像魔术,Get 会找到你的控制器,并将其提供给你。你可以实例化 100 万个控制器,Get 总会给你正确的控制器。
然后你就可以恢复你在后面获得的控制器数据。
// https://www.huizhanii.com
Text(controller.textFromApi);
项目结构
页面层:即业务逻辑
组件层:每个页面通用的功能组件
服务层:不依赖于业务的核心功能模块
框架层:即 Flutter 的两个 UI 框架
数据流程
Cache 本地缓存直接读取
Repository-Provider 网络数据
页面内的数据流转
页面代码拆分也是 MVC 和响应式的设计思想,拆分成 Controller、View、State。
结语:
综上所述,这种架构模式具有模板化的特点,能够实现解耦和扩展,而不会增加过多的复杂性,特别适用于中小型 App 的应用场景。
架构的目的在于解决复杂性问题。
当项目团队规模较小时,过度关注组件化和代码隔离会增加团队的心智负担,过于细分工作并不能带来良好的效果。每种架构都是一个平衡的结果,必须根据团队的实际情况进行取舍,不能盲目追求高大上。
转载请注明:汇站网 » 基于 GetX 的 Flutter 项目架构设计方案是一种用于开发 Flutter 应用程序的设计方案