MVVM 与 Bloc 模式
MVVM vs Bloc patterns
我正在使用 Flutter 创建一个新的应用程序,我正在尝试设计它,将业务逻辑与视图分开。
我读过有关 Bloc 和 MVVM 的内容(我知道还有其他模式,但我更喜欢这些模式),但我不明白它们之间的区别。它们在我看来几乎一样。
有谁能帮我理解一下吗?
查看 MVVM (source) 的插图:
您可以看到有单独的数据和业务逻辑模型。但是,使用 BLoC 并没有真正的区别。处理业务逻辑的类也处理数据,这同样适用于MVVM。
公平地说,确实没有太大区别。要删除的 关键部分 对两者都是相同的:将业务逻辑与 UI 隔离。因此,两者的实现看起来非常相似,即使用 Stream
's 和 StreamBuilder
' s.
此外,还有一些软件包可以使 Stream
的工作变得更容易,例如rxdart
就我而言,这是 Flutter 团队使用的。
它们并不完全相同,实际上... MVVM 意味着视图和视图模型之间的数据绑定,这意味着,在实践中,视图对象主要是控制视图模型的对象。在我看来,MVVM 似乎是 MVC 的简化,以在幕后“按原样”展示模型。例如,Xamarin 主要使用 MVVM,屏幕上的控件(如复选框、文本输入等)都会在幕后修改模型视图。
您可能已经开始在这里看到一个问题:如果您更改 UI,您可能还必须更改 MV。假设你有一个必须在 0-255 之间的条目号,你把这个逻辑放在哪里?嗯,在 MVVM 上,你把这个逻辑放在视图上。但是你必须把这些锁也放在模型视图上,以保证数据安全。这意味着要重写很多代码来做同样的事情。如果您决定更改此范围,则必须更改两个地方,这会使您的代码更容易出错。 免责声明:有解决方法,但比应该的要复杂得多。
另一方面,BLoC 通过接收事件和发射状态来工作。它不关心(尽管它可能)事件来自哪里。使用上面的相同示例,视图将向 bloc/controller 发出一个事件信号“嘿,我的号码变了!”,然后 bloc 将处理这个新事件,如果合适的话,向 UI:“嘿UI!你应该改变!我有一个新状态给你!”。然后,UI 重建自身以呈现这些更改。
对我来说,BLoC 优于 MVVM 的优势在于业务逻辑可以完全 与视图分离,这总体上是一种更好的做事方式。由于我们的现代软件开发需要对 UI 进行越来越多的更改(不同的屏幕尺寸、密度、平台等),因此 UI 端与模型分离是代码可重用性的一个极好的特性.
引入 BLoC 时,BLoC 和 MVVM 似乎有所不同,但随着 BLoC 实现的变化,这种差异逐渐消失。 现在唯一真正的区别是 BLoC 没有指定单独的表示逻辑和业务逻辑,或者至少它没有以明显的方式指定。表示逻辑是层了解 UI 元素与应用程序的业务部分(MVP 中的 Presenter 作业)之间的交互。一些 BLoC 实现将表示逻辑放入 BLoC,另一些则放入 UI.
BloC 中的新事物是它不应该公开任何方法。相反,它只会通过其暴露的一个或多个接收器接受事件。这是为了 Angular Dart 网络应用程序和 Flutter 移动应用程序之间的代码重用。这个概念最近被放弃了,因为我们并没有真正编写 Angular Dart web 应用程序,而且它不如常规方法方便。现在官方 BLoC 包中的块公开方法就像好的 ol' VM。
有人会说BLoC应该暴露一个完整状态对象的Stream,而VM可以暴露多个Streams,其实不然。在这两种方法中,公开一个状态流都是一种很好的做法。起初,官方 Google BLoC 演示文稿也介绍了使用多个输出流实现的 BLoC。
一个有趣的区别似乎是 BLoC 应该通过事件不仅与 UI 通信,而且与应用程序的不同部分通信。例如,它应该在收到 Firebase 通知后或存储库数据更改时收到事件。虽然这看起来很有趣,但我从未见过这样的实现。从技术角度来看这会很奇怪(存储库必须知道所有使用它的 BLoC???)。虽然我正在考虑尝试这样一个基于 EventBus 的实现,但这完全是题外话:)
我正在使用 Flutter 创建一个新的应用程序,我正在尝试设计它,将业务逻辑与视图分开。
我读过有关 Bloc 和 MVVM 的内容(我知道还有其他模式,但我更喜欢这些模式),但我不明白它们之间的区别。它们在我看来几乎一样。
有谁能帮我理解一下吗?
查看 MVVM (source) 的插图:
您可以看到有单独的数据和业务逻辑模型。但是,使用 BLoC 并没有真正的区别。处理业务逻辑的类也处理数据,这同样适用于MVVM。
公平地说,确实没有太大区别。要删除的 关键部分 对两者都是相同的:将业务逻辑与 UI 隔离。因此,两者的实现看起来非常相似,即使用 Stream
's 和 StreamBuilder
' s.
此外,还有一些软件包可以使 Stream
的工作变得更容易,例如rxdart
就我而言,这是 Flutter 团队使用的。
它们并不完全相同,实际上... MVVM 意味着视图和视图模型之间的数据绑定,这意味着,在实践中,视图对象主要是控制视图模型的对象。在我看来,MVVM 似乎是 MVC 的简化,以在幕后“按原样”展示模型。例如,Xamarin 主要使用 MVVM,屏幕上的控件(如复选框、文本输入等)都会在幕后修改模型视图。
您可能已经开始在这里看到一个问题:如果您更改 UI,您可能还必须更改 MV。假设你有一个必须在 0-255 之间的条目号,你把这个逻辑放在哪里?嗯,在 MVVM 上,你把这个逻辑放在视图上。但是你必须把这些锁也放在模型视图上,以保证数据安全。这意味着要重写很多代码来做同样的事情。如果您决定更改此范围,则必须更改两个地方,这会使您的代码更容易出错。 免责声明:有解决方法,但比应该的要复杂得多。
另一方面,BLoC 通过接收事件和发射状态来工作。它不关心(尽管它可能)事件来自哪里。使用上面的相同示例,视图将向 bloc/controller 发出一个事件信号“嘿,我的号码变了!”,然后 bloc 将处理这个新事件,如果合适的话,向 UI:“嘿UI!你应该改变!我有一个新状态给你!”。然后,UI 重建自身以呈现这些更改。
对我来说,BLoC 优于 MVVM 的优势在于业务逻辑可以完全 与视图分离,这总体上是一种更好的做事方式。由于我们的现代软件开发需要对 UI 进行越来越多的更改(不同的屏幕尺寸、密度、平台等),因此 UI 端与模型分离是代码可重用性的一个极好的特性.
引入 BLoC 时,BLoC 和 MVVM 似乎有所不同,但随着 BLoC 实现的变化,这种差异逐渐消失。 现在唯一真正的区别是 BLoC 没有指定单独的表示逻辑和业务逻辑,或者至少它没有以明显的方式指定。表示逻辑是层了解 UI 元素与应用程序的业务部分(MVP 中的 Presenter 作业)之间的交互。一些 BLoC 实现将表示逻辑放入 BLoC,另一些则放入 UI.
BloC 中的新事物是它不应该公开任何方法。相反,它只会通过其暴露的一个或多个接收器接受事件。这是为了 Angular Dart 网络应用程序和 Flutter 移动应用程序之间的代码重用。这个概念最近被放弃了,因为我们并没有真正编写 Angular Dart web 应用程序,而且它不如常规方法方便。现在官方 BLoC 包中的块公开方法就像好的 ol' VM。
有人会说BLoC应该暴露一个完整状态对象的Stream,而VM可以暴露多个Streams,其实不然。在这两种方法中,公开一个状态流都是一种很好的做法。起初,官方 Google BLoC 演示文稿也介绍了使用多个输出流实现的 BLoC。
一个有趣的区别似乎是 BLoC 应该通过事件不仅与 UI 通信,而且与应用程序的不同部分通信。例如,它应该在收到 Firebase 通知后或存储库数据更改时收到事件。虽然这看起来很有趣,但我从未见过这样的实现。从技术角度来看这会很奇怪(存储库必须知道所有使用它的 BLoC???)。虽然我正在考虑尝试这样一个基于 EventBus 的实现,但这完全是题外话:)