Closed peekpt closed 4 years ago
I think to get any further I'm going to need help from people who both do diagrams and are familiar with provider
. So I'm thinking that I should post an article to Medium.com showing my understanding in terms of these diagrams and asking for corrections or better approaches.
Good idea! Post the link here when it's done š
In fsct, it may be interesting to add the article in the Readme, until provider gets a proper website.
Remi, you've helped correct some of my misunderstandings, and I've incorporated those corrections into the diagrams, so I'd like to acknowledge your help in the article. At the same time, you express discomfort with the diagrams, so I don't want to create the impression that you approve of the approach. How would you like me to handle that? I could just reference this discussion, but I'm not sure we want everyone joining in here (or do we?).
Wait it provides a stream or a streamcontroller?
Remi, you've helped correct some of my misunderstandings, and I've incorporated those corrections into the diagrams, so I'd like to acknowledge your help in the article. At the same time, you express discomfort with the diagrams, so I don't want to create the impression that you approve of the approach. How would you like me to handle that? I could just reference this discussion, but I'm not sure we want everyone joining in here (or do we?).
I find them difficult to understand, but as long as they are "correct", then there's nothing wrong with showing them. So I'll gladly accept to add a link in the readme to redirect to your article š
On the other hand, adding them directly inside the readme (not as a link) may make peoples "fear" provider
a bit if they don't understand these graphs
If anyone could possible do an animated diagram like the ones in RxDart, easy to understand.
Yeah that's what I mentionned earlier.
RxDart's graph does not really fit provider, but something animated using flutter_web is definitely a good idea
I was thinking of something that looks like a widget tree
It can be a presentation converted to gif, or a video with voice over
With flutter_web I really think a playground is ideal.
Something like that
On the other hand, adding them directly inside the readme (not as a link) may make peoples "fear"
provider
a bit if they don't understand these graphs
Excellent point. If they don't understand the diagram outright, they might move on.
I see three possible levels of abstraction for a GIF animation, where value is an instance of data that provider makes available to consumers:
Text
widget that shows the latest value rendered within the text.Would something like this work? This is the most abstract way to do it.
That model mainly works for streams and futures. I'd probably want a different one for listenables.
IMO animated diagrams should be a codelab using flutter web.
Because provider has other "gotcha" that can't be represented using such diagram, like providers being scoped to a widget tree
IMO animated diagrams should be a codelab using flutter web.
Can you embed that in the documentation? In the README?
No. But the readme is starting to get pretty big already.
I'm thinking of hosting an actual website generated from markdown files, which would support iframes
Okay, so I'm thinking the README at least needs a clear description of the architecture, but that description would benefit from a diagram or two, even if oversimplified. The text can explain the missing details.
It's usually best to communicate a new idea incrementally, anyway. Besides, when I'm trying to decide which packages to investigate, I want a high level description to help me decide whether to proceed, before I invest time trying to learn the system through something interactive.
Here's an attempt to illustrate a listenable provider.
Or if you want to be clear that the listenabel has only one subscriber and not one for each consumer:
EDIT: Replaced with a drawing more suggestive of the consumers having access to the listenable.
Do you have a better name for this diagram? I also thought of "provider pattern," but I don't plan to speak of the pattern generically, only with respect to the provider
package.
(Revised). The text refers to this as "the provider architecture at a conceptual level."
What about "provider's data flow" ?
What about "provider's data flow" ?
It shows that, but it also shows control flow and structure, at least at a very high level.
I mainly don't want readers to think that I'm diagramming the design of your implementation. This is instead a way to think about the package for purposes of using it.
Calling it the "provider pattern" might properly convey that notion.
I've been struggling with the text and the diagrams around the word "value." This term is a parameter name for state data and data sources. Among data sources, it is both the injected data (listeners) and a data source for the injected data (futures and streams). I think I have to relegate it to being a parameter name and nothing more.
Is "data" the intended way to refer to state in provider? I'm having trouble using that term too because this is a mass noun in normal English. "Datum" is the singular, but nobody likes reading that word.
So I'm inclined to refer to "state" and map that term to and from the terms "value" and "data" (e.g. "initialData").
Unless someone can recommend a better way?
Mapping things out, it seems that my error is in always thinking that the data is state. The data is just some value. The only ambiguity is in the name of the provider value
parameter. Sometimes it's the data itself, sometimes it's a data source.
I think I'll proceed with the "value" language but distinguish the value from the provider value
parameter, which isn't always the value delivered to the consumer.
Provider<T>
provider value: T (data)
consumer value: T (data)
ListenableProvider<T>
provider value: T implements Listenable (data)
consumer value: T implements Listenable (data)
ChangeNotifierProvider<T>
provider value: T with ChangeNotifier (data)
consumer value: T with ChangeNotifier (data)
ValueNotifierProvider<T>
provider value: ValueNotifier<T> (data source)
consumer value: T (data)
StreamProvider<T>
provider value: Stream<T> (data source)
consumer value: T (data)
StreamProvider<T>.controller
provider value: StreamController<T> (data source)
consumer value: T (data)
FutureProvider<T>
provider value: Future<T> (data source)
consumer value: T (data)
Nope, it's not working. I'm having to use the word "state" instead of "value." The provider maintains the state for passing on to the consumers. If I show providers maintaining something called "value" being passed on to consumers, and the API sometimes called a data source (e.g. a future or stream) a value
, then the diagrams suggest that the future or stream gets passed to the consumer as the value
parameter of builder()
. The diagrams are supposed to help clarify, not confuse, so I think I have to avoid using the word "value" except in code samples.
I'm about halfway done with the article. Writing forces me to achieve clarity and my diagrams have been evolving accordingly. I can see why you might have had misgivings with my initial diagrams! Here's my latest "architecture" diagram:
Nice!
What are the numbers referring to? Like 1, 8: build
, what are these 1, 8
?
Nice!
Thanks! It's starting to look pretty, anyway.
What are the numbers referring to? Like
1, 8: build
, what are these1, 8
?
Sequence of events, numbered 1 through 11 here.1, 8: build
means that the first and eighth events are builds.
There really are two sequences here, 1 through 4 and 5 through 11. I'd rather not present 5 as necessarily following 4, but I haven't found a better way to put it all in one diagram. The only alternative I came up with was to number them either 1A-5A and 1B-7B or 1A-1E and 2A-2G, but those approaches made the diagram quite a bit harder to read, even using lowercase letters.
The article discusses these sequences separately and should clarify the diagram.
FYI, I've already changed 2, 9: request T state
to 2, 9: request T, optionally subscribe
.
Nice!
Also, it's only nice looking because provider is elegantly designed. This is your architecture. Powerfully flexible, and yet so simple -- and why I've chosen to embrace it.
Okay Remi, I've finally got drafts to share with you. I'd be grateful for any feedback you can offer, particularly letting me know anything I've got wrong.
I don't state why I wrote this series of articles until the conclusion:
"I wrote this series of articles primarily to help myself come to a better understanding of the provider package and how it works with Flutter. While I'm not new to Android development, I am new to Flutter and reactive programming. This series documents the pieces I felt I was missing. I put a little extra effort into it hoping to help other Flutter newbies."
I made a change. I moved discussion of dependency injection from the first article to a new section in the last article called "Dependency Injection and Data Binding."
I tried to avoid describing things as "binding" because the docs don't do that, but now that I'm done, I'm thinking the language of the article could have been a bit simpler had I referred to injecting values, some of which are bindable. As you see from my original UML above, I actually started in that direction. I moved away from it because I didn't want to be seen as offering a new take on what you did. But the 'state' language doesn't work for constant dependencies.
Maybe all I need to do is change "state" to "value" and "state source" to "value source."
Or maybe I could say that a provider provides "values" and when constructed with a "state source" the value is a "state." Then I can refer to injecting unchanging values and changing state. This should be a pretty simple fix, although extensive.
I'm gearing up for revising everything using "value," either "state source" or "data source," and saying that the value is a "state" when using a state source (or data source). There will be more to do than just simple word replacement, as I'll need to emphasize the use of non-state values early on.
I'm not keen on calling it "injection" and "injecting" throughout the article. I'd rather say "shares", "provides", or "exposes to," and leave discussion of dependency injection for the end.
For the record, I've decided to go with "state source" rather than "data source" because I'm more comfortable calling a model the former. I'm now changing the emphasis in the articles from states to values, making state one use case for values.
Okay, I've finished revising the articles to refer to "values" as much as possible. A value is a "state value" or "state" when supplied by a state source. This was a bit challenging to do while keeping everything clear. I had to reword quite a few sentences.
Most of the edits are minor, but I did add two paragraphs to the "Providing Values" section in the first article explaining what values are and why provider "provides" them.
I've posted them as three new articles. I'll keep the prior articles around a little while longer.
As usual, I'm eager for your feedback. Once I'm happy with them, I'll submit them to a Medium publications, probably Flutter Community.
Thanks!
I'm preparing for a talk in Greece tomorrow, so I'm a bit busy. I'll take a look this week-end
I'm preparing for a talk in Greece tomorrow, so I'm a bit busy. I'll take a look this week-end
Blow them away with your talk! I'll wait 'til next week to publish, then. Thanks so much!
Hey @rrousselGit, how did your talk go? Are you still planning to get to my articles this weekend?
@rrousselGit, thank you for all your notes so far. I believe I've accommodated all of them.
@jtlapp what a great series of articles !!! Your explanations are so well structured and clear, really really impressive.
Here are some modest notes I took while reading your articles :
Article 1 : in section "Architecture for Retrieving Values", maybe it would be useful for beginners to mention again 'Consumer' (and the fact that Consumer is part of the provider package). Provider.of
Article 2 : parts of the conclusion confuse me :
"The provider subscribes to the state source to receive state change notices. Some state sources provide the new state value along with the notice. Futures and streams are examples of such state sources. Other state sources, such as ValueListenable (including ChangeNotifier), only provide the notice. " -> (I really like the disctinction between 'state source' and 'state value' :+1: ) You wrote 'ValueListenable (including ChangeNotifier)', ChangeNotifier is not a ValueListenable, did you mean 'Listenable' here ?
"In this latter case, the provider retrieves the state value from the state source, except when the state source is itself the value provided to dependents." -> If "in this latter case" refers to ValueListenable and ChangeNotifier, i'm puzzled with the word "except" because with ChangeNotifier the value provided will be mostly the state source, no ?
"When using a ChangeNotifier, or when using a ValueListenable with a ValueListenableProvider, the state source is the value provided to dependents. The dependents themselves read state directly from the state source, or they directly access the state source to change its state." -> I have yet to use ValueListenableProvider ;-), but I understood that it provides the value from the ValueListenable. Maybe you meant 'Listenable' and 'ListenableProvider' ?
Keep up the good work !
@jtlapp what a great series of articles !!! Your explanations are so well structured and clear, really really impressive.
Thank you so much!
Here are some modest notes I took while reading your articles :
- Article 1 : in section "Architecture for Retrieving Values", maybe it would be useful for beginners to mention again 'Consumer' (and the fact that Consumer is part of the provider package). Provider.of is really what does the job, but beginners are more exposed to examples that uses 'Consumer'. It is just a suggestion : as you wrote in your third articles, your series is not meant to be a tutorial, so referring only to the fundation (Provider.of) is understandable.
Good idea. I'll look at moving the first mention of Consumer up to that section.
- Article 2 : parts of the conclusion confuse me :
"The provider subscribes to the state source to receive state change notices. Some state sources provide the new state value along with the notice. Futures and streams are examples of such state sources. Other state sources, such as ValueListenable (including ChangeNotifier), only provide the notice. " -> (I really like the disctinction between 'state source' and 'state value' š ) You wrote 'ValueListenable (including ChangeNotifier)', ChangeNotifier is not a ValueListenable, did you mean 'Listenable' here ?
Oops, that should have been "'ValueListenable (including ValueNotifier)'". Good catch!
"In this latter case, the provider retrieves the state value from the state source, except when the state source is itself the value provided to dependents."
-> If "in this latter case" refers to ValueListenable and ChangeNotifier, i'm puzzled with the word "except" because with ChangeNotifier the value provided will be mostly the state source, no ?
Yeah, I think you're puzzled because it was ChangeNotifier that was incorrect -- it should have been ValueNotifier.
"When using a ChangeNotifier, or when using a ValueListenable with a ValueListenableProvider, the state source is the value provided to dependents. The dependents themselves read state directly from the state source, or they directly access the state source to change its state." -> I have yet to use ValueListenableProvider ;-), but I understood that it provides the value from the ValueListenable. Maybe you meant 'Listenable' and 'ListenableProvider' ?
Another good catch. Yes, I meant Listenable with ListenableProvider. Looks like I was tying myself in knots!
Thank you for taking the time to review my articles!
-> If "in this latter case" refers to ValueListenable and ChangeNotifier, i'm puzzled with the word "except" because with ChangeNotifier the value provided will be mostly the state source, no ?
Oh, this exception is confusing after making the correction. I don't even need it, because the next paragraph says everything. Deleted. Thanks so much!
@bleroux, may I thank you for your feedback by name at the end of the article? If so, I'll need your name!
I haven't gotten any more feedback in a while, so I assume it's ready to go.
Thank you everyone for your help! Here are my achnowledgements. Let me know if you'd like something different:
I am grateful to Remi Rousselet, the author of the provider package, for patiently answering my many questions and for enduring my failed early efforts to produce diagrams capturing the provider architecture. I also thank Remi Rousselet, Bruno Leroux, and Brady Trainor for their feedback on earlier drafts of this series. Any issues that remain are entirely my responsibility.
Okay, I'm all set to submit to the Flutter Community publication on Medium. I'll go ahead and submit this evening if I don't get any more feedback.
@jtlapp Is there a link you can post here?
The articles are now all published in Flutter Community on Medium.com.
(Updated links for final publication on Medium)
I did this simple sketch example, I'm no expert, but I think if the dev team adds diagrams to documentation will help a lot people that are starting to learn this Plugin. There's information missing like how the values behave, how they update, etc... With all this providers and ways to reach the provided values it is start to get confusing.