对 Bloc 使用单例

Posted

技术标签:

【中文标题】对 Bloc 使用单例【英文标题】:Using a singleton for Bloc 【发布时间】:2019-07-31 21:33:16 【问题描述】:

我知道我的一些 BLOC 在整个应用生命周期中只会被实例化一次。 将这些 BLOC 类创建为单例是不好的做法还是反模式。 Singleton 可以帮助在任何地方访问 BLOC,并确保该类只被实例化一次。

当在另一个 BLOC 中使用一个 BLOC 并传递单例时,我还可以确保安全,就像它是“只是另一个”实现一样。

这样做可能会产生什么影响?

编辑

我有两个集团

    AuthenTicationBloc - 这是一个全球性集团 UserBloc - 应该只存在一次(单例)

AuthenTicationBloc 必须使用其中的 UserBloc。如果我将 UserBloc 设为单例,那么将其用作 UserBloc() 会很容易。

否则我必须在 AuthenTicationBloc 中创建 UserBloc 作为实例变量,如下所示:

class AuthenTicationBloc 
  UserBloc _userBloc;

  AuthenTicationBloc(@required UserBloc userBloc) : _userBloc = userBloc;


  myMethod()
    //use the userBloc
    _userBloc.setDetails();
  



runApp(
  UserBloc userBloc = UserBloc();

  Provider(
    value: AuthenTicationBloc(userBloc: userBloc),
    child: MyApp(),
  ),
);

如果我必须在其他地方使用小部件链中的 UserBloc,我必须让 UserBloc 也按如下方式全局提供,对吗?

UserBloc userBloc = UserBloc();

MultiProvider(
  providers: [
    Provider<AuthenTicationBloc>(
      value: AuthenTicationBloc(userBloc:userBloc),
    ),
    Provider<UserBloc>(
      value: userBloc,
    ),
  ],
  child: MyApp(),
);

【问题讨论】:

【参考方案1】:

行为保持不变。单例 vs InheritedWidget 变化不大

但它会产生一些架构后果,因为您应该将 InheritedWidget 用于不“在整个应用生命周期中仅实例化一次”的 BLoC。

这意味着:

您将在应用程序中混合使用 InheriedWidget 和 Singleton。降低一致性,因为您有两种不同的方式来创建/使用 BLoC 当规格发生变化时,它变得更难适应。很有可能在将来,您可能需要多次实例化它。这意味着您必须编辑整个应用程序

另一方面,单例不能防止 InheritedWidgets 会犯的一些错误。

例如,使用 InheritedWidgets 是不可能实现循环依赖的,而使用单例绝对是可能的。


就代码而言,使用 Singleton 与 InheritedWidget 也不会带来太多好处。

Pub 上有大量库可以让您的工作更轻松。包括provider:

runApp(
  Provider(
    value: MyBloc(),
    child: MyApp(),
  ),
);

【讨论】:

感谢您的解释。循环依赖可能会成为一个问题。我使用单例的情况更多的是在另一个集团中使用它,而不是将其创建为属性。请参阅我对问题的编辑。 InheritedWidgets 需要将 BLoC 作为参数传递而不是直接使用变量这一事实是它防止循环依赖的原因。

以上是关于对 Bloc 使用单例的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 blocTest 对 bloc 进行单元测试?

Flutter - 使用国际翻译对 Cubit/ Bloc 内的消息进行应用本地化

颤振:在 BLoC 中,事件比较失败,尽管使用 equatbale

使用 Flutter BLoC 模式跟踪多个状态

将flutter_bloc与tabview一起使用

Flutter:我可以在 BLoC 架构中使用 setState() 吗?