MVVM与Bloc模式

nie*_*gus 5 mvvm flutter bloc

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

我已经读过有关Bloc和MVVM的信息(我知道还有其他模式,但是我更喜欢这些模式),但是我不了解它们之间的区别。在我看来,它们几乎一样。

有谁能帮助我了解他们?

cre*_*not 14

看看这个MVVM 的插图(来源):

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

公平地说,确实没有太大区别。两者的关键部分是相同的:将业务逻辑与 UI 隔离。因此,两者中任何一个的实现看起来都非常相似,即使用Stream's 和StreamBuilder's。
此外,还有一些包可以让Stream's 的工作变得更容易,例如rxdart,就我而言,这是 Flutter 团队使用的。

  • 如果我明白你的意思,Bloc 是 MVVM 的实现吗? (2认同)

rdn*_*ega 10

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

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

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

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

  • 这是不正确的:“假设你有一个必须在 0-255 之间的条目号,你把这个逻辑放在哪里?好吧,在 MVVM 上你把这个逻辑放在视图上。” MVVM 的真正目的是将逻辑和 UI 分离。这与你所做的完全相反。 (4认同)
  • 您的 mvvm 评论无效。您可以将限制放入视图模型中,并让视图将其用作该限制的唯一来源。 (2认同)

Mic*_*oka 9

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

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

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

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