rrousselGit / provider

InheritedWidgets, but simple
https://pub.dev/packages/provider
MIT License
5.12k stars 512 forks source link

[REQ] Documented diagrams #83

Closed peekpt closed 4 years ago

peekpt commented 5 years ago

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.

Provider

jtlapp commented 5 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.

rrousselGit commented 5 years ago

Good idea! Post the link here when it's done šŸ˜Š

rrousselGit commented 5 years ago

In fsct, it may be interesting to add the article in the Readme, until provider gets a proper website.

jtlapp commented 5 years ago

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?).

peekpt commented 5 years ago

Wait it provides a stream or a streamcontroller?

rrousselGit commented 5 years ago

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

peekpt commented 5 years ago

If anyone could possible do an animated diagram like the ones in RxDart, easy to understand.

rrousselGit commented 5 years ago

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

peekpt commented 5 years ago

It can be a presentation converted to gif, or a video with voice over

rrousselGit commented 5 years ago

With flutter_web I really think a playground is ideal.

Something like that

jtlapp commented 5 years ago

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.

jtlapp commented 5 years ago

I see three possible levels of abstraction for a GIF animation, where value is an instance of data that provider makes available to consumers:

jtlapp commented 5 years ago

Would something like this work? This is the most abstract way to do it.

sequence1

jtlapp commented 5 years ago

That model mainly works for streams and futures. I'd probably want a different one for listenables.

rrousselGit commented 5 years ago

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

jtlapp commented 5 years ago

IMO animated diagrams should be a codelab using flutter web.

Can you embed that in the documentation? In the README?

rrousselGit commented 5 years ago

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

jtlapp commented 5 years ago

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.

jtlapp commented 5 years ago

Here's an attempt to illustrate a listenable provider.

seq listenable1

jtlapp commented 5 years ago

Or if you want to be clear that the listenabel has only one subscriber and not one for each consumer:

pure listenable3

EDIT: Replaced with a drawing more suggestive of the consumers having access to the listenable.

jtlapp commented 5 years ago

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.

provider_architecture

(Revised). The text refers to this as "the provider architecture at a conceptual level."

rrousselGit commented 5 years ago

What about "provider's data flow" ?

jtlapp commented 5 years ago

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.

jtlapp commented 5 years ago

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?

jtlapp commented 5 years ago

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)
jtlapp commented 5 years ago

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.

jtlapp commented 5 years ago

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:

uml provider_architecture 150pct

rrousselGit commented 5 years ago

Nice!

What are the numbers referring to? Like 1, 8: build, what are these 1, 8?

jtlapp commented 5 years ago

Nice!

Thanks! It's starting to look pretty, anyway.

What are the numbers referring to? Like 1, 8: build, what are these 1, 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.

jtlapp commented 5 years ago

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.

jtlapp commented 5 years ago

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."

jtlapp commented 5 years ago

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."

jtlapp commented 5 years ago

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.

jtlapp commented 5 years ago

Maybe all I need to do is change "state" to "value" and "state source" to "value source."

jtlapp commented 5 years ago

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.

jtlapp commented 5 years ago

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.

jtlapp commented 5 years ago

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.

jtlapp commented 5 years ago

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.

rrousselGit commented 5 years ago

Thanks!

I'm preparing for a talk in Greece tomorrow, so I'm a bit busy. I'll take a look this week-end

jtlapp commented 5 years ago

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!

jtlapp commented 5 years ago

Hey @rrousselGit, how did your talk go? Are you still planning to get to my articles this weekend?

jtlapp commented 5 years ago

@rrousselGit, thank you for all your notes so far. I believe I've accommodated all of them.

bleroux commented 5 years ago

@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 :

"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 commented 5 years ago

@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!

jtlapp commented 5 years ago

-> 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!

jtlapp commented 5 years ago

@bleroux, may I thank you for your feedback by name at the end of the article? If so, I'll need your name!

jtlapp commented 5 years ago

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.

jtlapp commented 5 years ago

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.

stargazing-dino commented 5 years ago

@jtlapp Is there a link you can post here?

jtlapp commented 5 years ago

The articles are now all published in Flutter Community on Medium.com.

(Updated links for final publication on Medium)