【问题标题】:MVVM vs Bloc patternsMVVM 与 Bloc 模式
【发布时间】:2019-07-23 09:19:51
【问题描述】:

我正在使用 Flutter 创建一个新应用,并且我正在尝试设计它,将业务逻辑与视图分离。

我读过 Bloc 和 MVVM(我知道还有其他模式,但这些是我更喜欢的模式),但我不明白它们之间的区别。在我看来,它们几乎相同。

有人可以帮我理解它们吗?

【问题讨论】:

  • BLoC 是一种模式,是根据 Flutter 架构的具体情况专门为 Flutter 设计的。是的 - 它们非常相似

标签: mvvm flutter bloc


【解决方案1】:

查看MVVM (source) 的插图:

您可以看到有单独的数据和业务逻辑模型。但是,使用 BLoC 并没有真正的区别。处理业务逻辑的类也处理数据,这也适用于 MVVM

说句公道话,其实差别不大。 关键部分对于两者来说都是相同的:将业务逻辑与 UI 隔离。因此,两者的实现看起来非常相似,即使用 StreamStreamBuilder
此外,还有一些软件包可以更轻松地使用 Stream,例如rxdart 就我而言,这是 Flutter 团队使用的。

【讨论】:

  • 如果我明白你的意思,Bloc 是 MVVM 的实现吗?
  • @niegus 你可以这样说。
【解决方案2】:

实际上它们并不完全相同... MVVM 意味着视图和视图模型之间的数据绑定,这意味着,实际上,视图对象主要是控制视图模型的对象。在我看来,MVVM 是 MVC 的简化,在幕后“按原样”展示模型。例如,Xamarin 主要使用 MVVM 和屏幕上的控件,如复选框、文本输入等,都会在后台修改模型视图。

您可能已经开始在这里看到一个问题:如果您更改 UI,您可能还必须更改 MV。假设你有一个条目号必须在 0-255 之间,你把这个逻辑放在哪里?好吧,在 MVVM 上,你把这个逻辑放在视图上。但是您也必须将这些锁放在模型视图上以保证数据安全。这意味着要重写很多代码来做同样的事情。如果您决定更改此范围,则必须更改两个位置,这会使您的代码更容易出错。 免责声明:有一些解决方法,但比应有的复杂得多。

另一方面,BLoC 通过接收事件和发出状态来工作。它不关心(尽管可能)事件来自哪里。使用上面的相同示例,视图将通过“嘿,我的号码已更改!”向块/控制器发出一个事件信号,然后该块将处理这个新事件,并在合适的情况下向 UI 发出一个信号:“嘿 UI!你应该改变!我有一个新的状态给你!”。然后,UI 会自行重建以呈现这些更改。

对我来说,BLoC 相对于 MVVM 的优势在于业务逻辑可以完全从视图中解耦,这总体上是一种更好的做事方式。由于我们的现代软件开发需要对 UI 进行越来越多的更改(例如不同的屏幕尺寸、密度、平台等),因此将 UI 端与模型分离是代码可重用性的绝佳功能。

【讨论】:

  • 这不是真的:“假设你有一个条目号必须在 0-255 之间,你把这个逻辑放在哪里?嗯,在 MVVM 上你把这个逻辑放在视图上。” MVVM 的真正目的是将逻辑和 UI 分开。这与你所做的完全相反。
  • 这就是为什么我们在 ViewModel 上有一个 validate() 方法。业务逻辑验证不是 View 域。
  • 您的 mvvm 评论无效。您可以将限制放在视图模型中,并让视图将其用作该限制的唯一来源。
  • 为了透明度,这个问题有 7 个反对票和 17 个赞成票,而更受欢迎的 answer 根本没有反对票。当我不可避免地回到与建筑相关的问题时,这篇笔记既适用于我,也适用于其他人。 ? 我发现这个答案令人困惑。
【解决方案3】:

在引入 BLoC 时,BLoC 和 MVVM 似乎有所不同,但随着 BLoC 实现随着时间的推移而发生变化,这种差异逐渐消失。 目前唯一真正的区别是 BLoC 没有指定单独的表示逻辑和业务逻辑,或者至少它没有以明显的方式这样做。表示逻辑是理解交互的层在 UI 元素和应用程序的业务部分之间(MVP 中的 Presenter 工作)。一些 BLoC 实现将表示逻辑放入 BLoC,另一些则放入 UI。

BloC 中的新事物是它不应该公开任何方法。相反,它只会通过其暴露的接收器或接收器接受事件。这是为了 Angular Dart Web 应用程序和 Flutter 移动应用程序之间的代码重用。这个概念最近被放弃了,因为我们并没有真正编写 Angular Dart 网络应用程序,而且它不如常规方法方便。现在官方 BLoC 包中的 Blocks 公开了方法,就像好的 ol' VM 一样。

有人会说 BLoC 应该公开一个完整状态对象的 Stream,而 VM 可以公开多个 Stream,但事实并非如此。在这两种方法中,暴露一个状态流都是一种很好的做法。起初,Google BLoC 官方演示文稿还展示了使用多个输出流实现的 BLoC。

一个有趣的区别似乎是,BLoC 不仅应通过事件与 UI 进行通信,还应与应用程序的不同部分进行通信。例如,它应该在收到 Firebase 通知或存储库数据更改后收到一个事件。虽然这看起来很有趣,但我从未见过这样的实现。从技术角度来看这很奇怪(存储库必须知道所有正在使用它的 BLoC ???)。虽然我正在考虑尝试这种基于 EventBus 的实现,但这完全是题外话:)

【讨论】:

    猜你喜欢
    • 2019-02-07
    • 2019-05-23
    • 2011-10-28
    • 1970-01-01
    • 1970-01-01
    • 2019-07-19
    • 2019-03-31
    • 1970-01-01
    • 2012-08-16
    相关资源
    最近更新 更多