这是一系列出版物中的第一篇文章,解释了我对Flutter应用程序体系结构的理解。 我警告你-这将是非常自信的 。
到目前为止已计划:
前言
我从事编程已有20年了。 四年前,我开始使用Xamarin.Forms进行移动开发,因为跨平台是我作为独立开发人员的唯一动机。 Xamarin.Forms实际上促使您使用MVVM模式,因为UI是在XAML中定义的,并且您需要某种层将UI与模型粘合在一起。 在使用Xamarin的过程中,我遇到了ReactiveUI ,并被流和响应扩展( Rx )所吸引,这使我的应用程序更加可靠。
当Xamarin.Forms MVVM开箱即用时,当我切换到Flutter时,我很惊讶其中没有类似的设计模式。 我开始研究各种建议的方法,但是没有一个方法完全令我满意:
- InheritedWidget :我无法仅更新窗口小部件树中已更改的部分,因此我仅使用它来访问发布dart流(Dart流)的模型类,但很快放弃了这个想法,转而使用模板Service Locator
- 范围模型比
InheritedWidget
有趣,但是它没有像以前使用ReactiveUI一样给我带来很大的灵活性。 - Redux是许多熟悉React Native的开发人员推荐的模板。 关于我为什么不喜欢我的整篇文章。
- BLoC :如果在BLoC开始发展时我还没有开始开发自己的模式,那么我很可能会采用它,因为它确实具有灵活性和反应性。 我不喜欢它发布流接收器,而且我不能只是接受函数或命令并将其传递给窗口小部件的事件处理程序。 此外,BLoC不会告诉您如何整体构建应用程序,也没有明确定义某个BLoC应该有多大或其范围是什么
- MVVM :自从我和他一起工作以来,这是我希望在Flutter中实现的第一件事。 但是不! ViewModel的目的是通过绑定在View中优雅地提供模型的表示形式。 但是Flutter不会用新数据更新其模型,而是始终重建它们,正如我已经描述过的 。 此外,ViewModels应该始终与基本模型同步,这会导致令人不愉快的错误,现实表明,几乎无法实现在应用程序中重用ViewModels的预期优势。 亚当·佩德利(Adam Pedley) 关于这些缺陷的精彩文章
关于层冗余的苛刻事实
在开发过程中,您应该始终将应用程序划分为多层,这几乎是一个教条,因为每一层都只能访问底层,因为这将允许您:
- 在其他项目中重用图层
- 透明地将一层替换为另一层
- 简化测试
但是:
- 在我的实践中,从来没有发现层完全重用的情况。 如果您具有可以重用的通用代码,则将其放入某种通用库中更有意义。
- 更换整个层也不是常见的做法。 在应用程序达到一定开发阶段后,大多数人不太可能替换数据库,因此为什么要为其添加抽象层。 好吧,如果需要我们当前的某些开发工具,则重构非常容易;
- 真正有效的是简化测试
我不反对使用图层,但是,我们是否应该像以前一样鲁re地遵循此规则。 过度使用它们会导致代码增加,并可能在维护应用程序状态的单一来源的同时产生问题。 因此,请在确实需要时而不是基于“最佳实践”来应用图层。
Flutter的理想架构
那么,我对理想的架构有什么期望?
- 易于理解应用程序。 对我来说,这是最重要的目标。 涉及使用现有代码的新开发人员应该容易理解开发结构
- 团队发展的轻松
- 体系结构本身应该易于理解和维护。
- 在开发中没有拐杖的模板代码
- Flutter反应式样式支持
- 简易调试
- 性能不受影响
- 易于扩展
- 易于测试
- 专注于应用程序而不是徘徊在源代码中的机会
小部件独立性
基于无状态界面元素的性质,Flutter中的任何页面/小部件都不应依赖或影响他人。 这导致了这样一个想法,即每个页面/小部件都应独立负责显示自身及其与用户的所有交互。
接收虚拟机
RxVMS是先前文章中描述的RxVAMS模式的演变,在实际应用中已发现并解决了一些问题。
所有这些想法的当前结果是RxVMS或Rx-View-Managers-Services模式。 它执行上述所有任务,唯一的要求是您必须了解Rx线程和元素。 为了帮助您解决这个问题,我专门提供以下文章。
这是我的申请的简要概述

服务项目
这些是与外界的接口的抽象,可以用作数据库,REST API等。 它们不影响应用程序的状态。
管理人员
管理者对语义上相似的功能进行分组,例如身份验证,订购过程等。 管理者操纵对象的状态。
状态的任何更改(应用程序数据的更改)都只能通过管理员进行。 通常,管理人员自己不存储数据,除非对性能或运行时常数至关重要的情况除外。
如果服务请求后需要管理人员某些转换,则管理人员可以用作代理数据源。 一个示例是组合来自两个或多个源的数据以在视图中显示。
管理者可以相互交流。
观看次数
通常,这是StatefullWidget或StreamBuilder,它们能够使用来自管理器和服务的数据。 它可以是整个页面或小部件。 视图不存储任何状态,并且可以在遵守此规则的情况下直接与服务联系。
域对象
尽管未包含在图中,但它们是代表业务模型的重要实体。 在其他模式中,它们可以与业务逻辑一起属于一个单独的层( 业务模型 )。 在这里,在RxVMS中,它们不包含任何更改应用程序状态的逻辑。 几乎总是这些数据,它们是简单的数据类型- 普通数据对象 (如果我将它们包括在模式中,则看起来像RxVMMS,它有点长,并且会引起混淆-VM可能会误认为ViewModel)。 逻辑上, 域对象位于管理器层中。
以下文章将揭示这些元素的本质和相互作用。