brianegan / new_flutter_template

Test ideas for a new flutter template
140 stars 23 forks source link

MVC? MVP? MVVM? Naming is hard! #3

Open brianegan opened 3 years ago

brianegan commented 3 years ago

Looking at the documentation and example projects provided by popular State Management libraries, most separate Data Logic from Widget Logic, with some kind of object that connects them together (example: Bloc documentation). Although there are implementation differences between libraries, most of the times the logic in these "glue" or "connector" or "business logic" objects is very similar to one another (think of the logic that's often contained in a Cubit, StateNotifier, or ChangeNotifier).

Therefore it might be nice to give a general name to the patterns the community is already using so we can discuss concepts as a community more easily. What name would you use to describe this general pattern?

Relates to: https://github.com/brianegan/new_flutter_template/issues/2

angwandi commented 3 years ago

MVVM

brianegan commented 3 years ago

Thanks @angwandi! If you have an extra minute, could you please describe a bit more why MVVM makes the most sense to you? Thanks again :)

escamoteur commented 3 years ago

None of the above because Flutter is MVU because of its reactive nature. Trying to force any of the above patterns on a Flutter app makes it more complecated than needed. The problem is that none of the current libraries define an architecture for the whole app. That's why I started wot work on my RVMS architecture which tries to fill exactly this gap. It can be implemented with diffrent packages. But i its code it uses Views that get rebuild whenever a Manager publishes a change of the Apps data. And it separates a Service Layer to decouple your apps logic from the actuall device and environment where the App is executed.

irvine5k commented 3 years ago

Any architecture that can provide isolation of layers and modules, making the app flexible, testable, and simple to change. Maybe a simplified clean architecture.

brianegan commented 3 years ago

Thanks @escamoteur -- as a thought exercise: I'd be curious if we're actually talking about the same architecture but using different naming? For example, I'm thinking of the Model in these terms defined by Microsoft, which includes a service or repository layer: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/enterprise-application-patterns/mvvm#model

"Controllers" or "Presenters" or "ViewModels" in my mind glue the Model Layer & Views together in exactly the way you describe. Views can call methods on the "Controller" or "Presenter" or "ViewModel" which then might delegate some work to a Service -- once the service returns a response the "Controller" notify the View that new data is available (Thinking of the "Controller" as a ChangeNotifier, ValueNotifer, StateNotifier, Cubit, etc).

Does that make any sense or do you think we're still talking about something very different here?

brianegan commented 3 years ago

Also, I realized I forgot to link to this related issue: https://github.com/brianegan/new_flutter_template/issues/2

escamoteur commented 3 years ago

As someone using Xamarin Forms for more than two years, I can say that I'm quite familiar with the MVVM pattern. It only makes sense in a system that uses an markup UI defintion with automatic bindings. that's the reason you need a ViewModel at all as glue layer to your business logic.

I actually prefer talking of Presentation Layer, business layer and, and service layer.

controllers where only needed in systems where a third party had to inform as part of the UI that it has to update with new data or to transfer an user input to the business layer.

In an reactive environment like Flutter where we have Widgets like Stream- or ValueListenable- builders that update automatically while observing a property of a modell object we don't need such a thing as a controller anymore.

It's my conviction that none of the traditional UI/Model patterns fits Flutter. MVU is different from them and needs another structure.

escamoteur commented 3 years ago

As an addition, separating the model from a service or repository layer especially in connection with a ServiceLocator enables you to mock this layer easy for testing for to switchout backends

escamoteur commented 3 years ago

Also, I realized I forgot to link to this related issue: #2

I actually think this two issues should be one :-) what sense does it make to find a name and not a structure :-)

brianegan commented 3 years ago

In my crazy brain, there are two decisions to be made: What do we use to Glue the Model and View together (ChangeNotifier, ValueNotifier, Cubit, StateNotifier, etc) and then a second decision of what we call that thing. Perhaps it was a mistake :crying_cat_face:

brianegan commented 3 years ago

In an reactive environment like Flutter where we have Widgets like Stream- or ValueListenable- builders that update automatically while observing a property of a modell object we don't need such a thing as a controller anymore.

This is interesting as well -- may I ask what would you call the ValueNotifier or Object that holds the Streams that the Widget can listen to? Would you call that a "Manager" where I would call that a "Controller"?

escamoteur commented 3 years ago

I think you are mistaken here :-) all the glue you mentioned can act as the medium in an MVU sytem to trigger updates. As I see it there are only two technologies that are used here, Streams or any ChangeNotifier derived class. I think we better try to descibe the structure of the app to get to a more precise name :-)

This is interesting as well -- may I ask what would you call the ValueNotifier or Object that holds the Streams that the Widget can listen to? Would you call that a "Manager" where I would call that a "Controller"?

If this object does more than just host the Listenable I wouldn't call it a controller, because afaik the controller in the traditional patterns is a pure mediator that only decouples. I call them Managers because they get things done. In RVMS the whole intelligence of the app is implemented in Managers. For my understanding a manage is also more than a pure BloC because it bundles semantically or feature related functionality. So most Managers how I see them also have a long live time and don't get created and destroyed for every Page of an app. Managers also can use other managers to get their work done, so you could even imagine a manager that doesn't interact with the UI or a service at all.

brianegan commented 3 years ago

@escamoteur Thanks for that additional info!

chimon2000 commented 3 years ago

None of the above because Flutter is MVU because of its reactive nature. Trying to force any of the above patterns on a Flutter app makes it more complecated than needed. The problem is that none of the current libraries define an architecture for the whole app. That's why I started wot work on my RVMS architecture which tries to fill exactly this gap. It can be implemented with diffrent packages. But i its code it uses Views that get rebuild whenever a Manager publishes a change of the Apps data. And it separates a Service Layer to decouple your apps logic from the actuall device and environment where the App is executed.

My vote would also be for none of the above. I'd either make it specific to the state management chosen (notifiers for Value/ChangeNotifier, cubits for Bloc, etc.) or more generic (blocs, managers, etc.)

escamoteur commented 3 years ago

@chimon2000 don't mixup technologies with concepts. most of the existing state management solutions can be used in different architectures

chimon2000 commented 3 years ago

@chimon2000 don't mixup technologies with concepts. most of the existing state management solutions can be used in different architectures

That's fair, I was making an assumption that there was a 1-1 between the SM and the Architectural pattern.

brianegan commented 3 years ago

@chimon2000 Thanks for the input! What do you think of this statement?

Although there are implementation differences between libraries, most of the times the logic in these "glue" or "connector" objects is very similar to one another (think of the logic that's often contained in a Cubit, StateNotifier, or ChangeNotifier).

That's what got me when writing the different evaluations and architecture samples: If you look at what's contained in a Cubit, StateNotifier, ValueNotifier, or ChangeNotifier, it's all so similar. The example apps from almost all major packages follow a very similar pattern as well.

Therefore, perhaps part of this question is asking: Can we agree on some common terminology to help us discuss "State Management?" I thought it might be helpful to introduce some common terminology into the community so folks can discuss more concrete points, such as "I use bloc for my Controllers because I like the event-driven approach" rather than "I use bloc for my state management."

escamoteur commented 3 years ago

It would definitely help to get the focus off of the used technology to an architectural view. I honestly never liked the term state management. Interestingly while doing Xamarin I never heard it from anyone.

chimon2000 commented 3 years ago

@chimon2000 Thanks for the input! What do you think of this statement?

Although there are implementation differences between libraries, most of the times the logic in these "glue" or "connector" objects is very similar to one another (think of the logic that's often contained in a Cubit, StateNotifier, or ChangeNotifier).

That's what got me when writing the different evaluations and architecture samples: If you look at what's contained in a Cubit, StateNotifier, ValueNotifier, or ChangeNotifier, it's all so similar. The example apps from almost all major packages follow a very similar pattern as well.

Therefore, perhaps part of this question is asking: Can we agree on some common terminology to help us discuss "State Management?" I thought it might be helpful to introduce some common terminology into the community so folks can discuss more concrete points, such as "I use bloc for my Controllers because I like the event-driven approach" rather than "I use bloc for my state management."

Another option might just be bloc, referring to the pattern not the library. "Business logic components" is already specific enough to convey purpose but generic enough that it doesn't convey a particular pattern. For example "I use RxVMS for my BLoCs." It's kind of unfortunate that the library association is more common.

Arkangel12 commented 3 years ago

I definitely think this should not be taking care of here, people will think this is a rule and is a must to use the architecture defined by the team and this is not actually true, so maybe we should only add in the README.md file some links to examples that are already in use for other so the dev (newcomer) or not can make a desition.

brianegan commented 3 years ago

@Arkangel12 Thanks for the feedback!

Beginner-to-intermediate developers have told us they need concrete guidance on those kinds of decisions. Given that fact, do you think a README is the best solution? If not, how would you suggest we structure this template so it gives folks some concrete advice without being too strict?

Arkangel12 commented 3 years ago

yeah I think to add a small description for each one and a link to youtube/medium/blogs where they can find a deep implementation may people like MTechViral, Resocoder, Filledstack, and many more had created examples that could be used in this README.md I think is not a good idea to add so much information in the template, it should be used as a source for other resources.

asidt commented 3 years ago

I use an architecture which is inspired by Android Architecture Components which is well defined and not ambiguous. It's an MVVM. These are my layers: view - this is where all the Flutter UI widgets are. It contains pages and widgets viewmodel - this contains my ChangeNotifier(s) which are consumed by the views (it could be implemented in many other ways, but I follow the Simple State Management) model - this is the data layer, so it contains my Repositories, my db, my web services and my podos

lucamtudor commented 3 years ago

Aand I'm gonna throw some gas on this nice, educative & firey architecture discussion and suggest Square's Workflow approach to reactive declarative UI frameworks that feels right at home with Android's Compose & Apple's SwiftUI. Choosing a template architecture is always hard and dividing sooo... call it "unidirectional data flow thingy"? (I get some strong PTSD kicks whenever I find a WhateverManager).

icnahom commented 3 years ago

In MVC and MVP - the Controller and Presenter contains a reference to the View and updates it. In MVVM - the Model notifies, the ViewModel notices the change and fires, then the View that's observing it rebuilds.

So if we choose MVVM, our Model will be a Listenable, the ViewModel will be an InheritedNotifier (AnimatedBuilder + InheritedWidget/InheritedModel), and the View will observe the InheritedNotifier.

Somehow similar to what we saw in ScopedModel.

Check this Lecture Video on MVVM in SwiftUI. https://youtu.be/4GjXq2Sr55Q

b099l3 commented 3 years ago

Just throwing my 2 cents in.

I think none of the above, as naming it an existing pattern I think is slightly confusing. If you start calling Blocs VMs, I'm sure it would cause more confusion when the developers go on to look at other patterns. In terms of a general name for these patterns, I have also seen other documentation naming these patterns (MVVM, MVC, MVP, MVI, MVU, etc) as Data Flow patterns. Which I personally like as it describes exactly their purpose, trying to get the data to the screen be it uni-directional or bi-directional.

If you are trying to name the concept of the "object that connects them together" be that Presenter, Controller, ViewModel, Cubit, StateNotifier, ChangeNotifier, etc. I think, something that doesn't relate to one of the existing patterns, something generic like what has been stated above, "Glue" or "Propagator".

I understand that simplifying the naming adds the problem of knowing what that term represents but like you said naming is hard and getting it to click in someone head can be hard too. There are so many patterns and based on where the developer comes from, first time programming, web background, mobile background, these concepts can be hard to wrap your brain around, many melons have been melted 😁

When I was first doing my research into Flutter, I came from a native iOS(MVC, VIPER) and Xamarin(MVVM) background this was a great source https://dev.to/adammc331/mvwtf-demystifying-architecture-patterns-ap1

The video in this article is great https://www.youtube.com/watch?v=T7A-JbJBjyg