filiph/state_experiments

Question regarding Singleton

masseelch opened this issue · 2 comments

Hello,

i saw your video about state management and came here afterwards. (Great video, learned a lot and got a lot more questions)

Are there any drawbacks on using the inherited widgets as Providers for the BLoC's instead of a singleton? I just learned dart has any easy way to create singletons with factory constructors, so this seems like another (maybe good) way to go?

I have seen that you have one part of this repo which is called singleton, so i assume you did experiment with them. But why exactly do you seem to prefer the InheritedWidget way instead of the singleton?

I cannot find any questions anywhere concerning singletons vs InheritedWidget.

Thanks in advance for any answer :-)

JC

Thanks for the question!

The main difference between InheritedWidget and (the way we're using) a singleton is that the latter is used as a global variable. That means testing is really hard / impossible.

Take this fragment of a test:

final mockCart = MyMockCart();
return CartProvider(
  cart: mockCart,
  child: MyApp(),
);
expect(mockCart.triedContactingServer, isTrue);

In the example above, using something that's not a global variable allows us to mock it and then verify that MyApp uses the provided/inherited value correctly.

With a global variable, that's not possible. The app will always have access to that one Cart, which we won't be able to mock. That might mean that our tests are trying to actually contact the server, even in unit tests.

This is just one very concrete example why global singletons are not a good idea. There's a lot of discussion about other reasons to be found.

Singletons have their place (especially when they're not global, and when they stand for a resource that is always single — like the audio driver in games, for example). But for state management in a Flutter app, I'd recommend against them.

Still, we wanted to show it.

Let me know if that answers your question. I'm going to close this issue here. Feel free to re-open it. (But we might want to move this discussion elsewhere.)

Thanks for the fast reply. I somehow did not see the Email, so please forgive my late reaction.

There is another question, which i have now.

Lets assume i have multiple BLoCs which i then need multiple ProviderWidgets for.

Is there a "cleaner" solution to

return CartProvider(
  child: BLoCProvider2(
    child: BLocProvider3(
      child [... several more Providers ...],
        child: MyApp()
    ),
  ),
);